From 5ed4c0010b0e2c979547a12de623533d9ace4b7d Mon Sep 17 00:00:00 2001 From: Silverlan Date: Tue, 12 Nov 2024 20:22:48 +0100 Subject: [PATCH 01/64] feat(debug): add e-mail target address to crashdump information prompt --- .../scripts/localization/de/texts/prompts.txt | 2 +- .../scripts/localization/en/texts/prompts.txt | 2 +- .../scripts/localization/es/texts/prompts.txt | 2 +- .../scripts/localization/fr/texts/prompts.txt | 2 +- .../scripts/localization/it/texts/prompts.txt | 2 +- .../scripts/localization/jp/texts/prompts.txt | 2 +- .../scripts/localization/pl/texts/prompts.txt | 2 +- .../localization/zh-cn/texts/prompts.txt | 2 +- core/shared/src/debug/mdump.cpp | 27 ++++++++++--------- 9 files changed, 22 insertions(+), 21 deletions(-) diff --git a/assets/scripts/localization/de/texts/prompts.txt b/assets/scripts/localization/de/texts/prompts.txt index 5cc7ae304..9929855d4 100644 --- a/assets/scripts/localization/de/texts/prompts.txt +++ b/assets/scripts/localization/de/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "Ja" prompt_crash = "Es ist ein schwerwiegender Fehler im Programm aufgetreten. Möchten Sie eine Diagnose-Datei speichern? Diese Datei enthält Informationen über Ihr System und den Zustand des Spiels zum Zeitpunkt des Absturzes und kann von einem Entwickler verwendet werden, um das zugrunde liegende Problem zu beheben." prompt_crash_dump_archive_failed = "Fehler beim Speichern der Dump-Datei: {}" prompt_crash_dump_generation_failed = "Fehler beim Speichern der Dump-Datei in '{}': Fehlercode {}" -prompt_crash_dump_saved = "Dump-Datei in '{}' gespeichert. Bitte senden Sie diese an einen Entwickler, zusammen mit einer Beschreibung dessen, was Sie getan haben, um den Fehler auszulösen." +prompt_crash_dump_saved = "Dump-Datei in '{}' gespeichert. Bitte senden Sie diese an {} , zusammen mit einer Beschreibung dessen, was Sie getan haben, um den Fehler auszulösen." prompt_fallback_to_opengl = "Wenn dieser Absturz weiterhin besteht, kann das Wechseln zur OpenGL-Rendering die Lösung sein. Möchten Sie das jetzt versuchen?" \ No newline at end of file diff --git a/assets/scripts/localization/en/texts/prompts.txt b/assets/scripts/localization/en/texts/prompts.txt index 98ad2bf42..aaa16e263 100644 --- a/assets/scripts/localization/en/texts/prompts.txt +++ b/assets/scripts/localization/en/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "Yes" prompt_crash = "A terminal error has occurred in the program. Would you like to save a diagnostic file? This file contains information about your system and the state of the game at the time of the crash and can be utilized by a developer to fix the underlying problem." prompt_crash_dump_archive_failed = "Failed to save dump file: {}" prompt_crash_dump_generation_failed = "Failed to save dump file to '{}': Error code {}" -prompt_crash_dump_saved = "Saved dump file to '{}'. Please send it to a developer, along with a description of what you did to trigger the error." +prompt_crash_dump_saved = "Saved dump file to '{}'. Please send it to {} , along with a description of what you did to trigger the error." prompt_fallback_to_opengl = "If this crash persists, switching to OpenGL rendering may help resolve it. Would you like to try that now?" \ No newline at end of file diff --git a/assets/scripts/localization/es/texts/prompts.txt b/assets/scripts/localization/es/texts/prompts.txt index dd9f73800..d454ddefb 100644 --- a/assets/scripts/localization/es/texts/prompts.txt +++ b/assets/scripts/localization/es/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "Sí" prompt_crash = "Se ha producido un error terminal en el programa. ¿Le gustaría guardar un archivo de diagnóstico? Este archivo contiene información sobre su sistema y el estado del juego en el momento del fallo, y puede ser utilizado por un desarrollador para solucionar el problema subyacente." prompt_crash_dump_archive_failed = "No se pudo guardar el archivo de volcado: {}" prompt_crash_dump_generation_failed = "No se pudo guardar el archivo de volcado en '{}': Código de error {}" -prompt_crash_dump_saved = "Archivo de volcado guardado en '{}'. Por favor, envíelo a un desarrollador junto con una descripción de lo que hizo para provocar el error." +prompt_crash_dump_saved = "Archivo de volcado guardado en '{}'. Por favor, envíelo a {} , junto con una descripción de lo que hizo para activar el error." prompt_fallback_to_opengl = "Si este error persiste, cambiar a renderizado con OpenGL podría ayudar a resolverlo. ¿Le gustaría intentarlo ahora?" \ No newline at end of file diff --git a/assets/scripts/localization/fr/texts/prompts.txt b/assets/scripts/localization/fr/texts/prompts.txt index 2d71c99b2..f9649eea7 100644 --- a/assets/scripts/localization/fr/texts/prompts.txt +++ b/assets/scripts/localization/fr/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "Oui" prompt_crash = "Une erreur fatale est survenue dans le programme. Souhaitez-vous enregistrer un fichier de diagnostic ? Ce fichier contient des informations sur votre système et l'état du jeu au moment du crash et peut être utilisé par un développeur pour résoudre le problème sous-jacent." prompt_crash_dump_archive_failed = "Échec de l'enregistrement du fichier de vidage : {}" prompt_crash_dump_generation_failed = "Échec de l'enregistrement du fichier de vidage dans '{}': Code d'erreur {}" -prompt_crash_dump_saved = "Fichier de vidage enregistré dans '{}'. Veuillez l'envoyer à un développeur, accompagné d'une description de ce que vous faisiez pour provoquer l'erreur." +prompt_crash_dump_saved = "Fichier de vidage enregistré dans '{}'. Veuillez l'envoyer à {} , accompagné d'une description de ce que vous faisiez pour provoquer l'erreur." prompt_fallback_to_opengl = "Si ce crash persiste, passer au rendu OpenGL pourrait aider à le résoudre. Voulez-vous essayer maintenant ?" \ No newline at end of file diff --git a/assets/scripts/localization/it/texts/prompts.txt b/assets/scripts/localization/it/texts/prompts.txt index e767a5065..2944eda5c 100644 --- a/assets/scripts/localization/it/texts/prompts.txt +++ b/assets/scripts/localization/it/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "Sì" prompt_crash = "Si è verificato un errore fatale nel programma. Vuoi salvare un file diagnostico? Questo file contiene informazioni sul tuo sistema e lo stato del gioco al momento del crash e può essere utilizzato da uno sviluppatore per risolvere il problema sottostante." prompt_crash_dump_archive_failed = "Impossibile salvare il file di dump: {}" prompt_crash_dump_generation_failed = "Impossibile salvare il file di dump in '{}': Codice errore {}" -prompt_crash_dump_saved = "File di dump salvato in '{}'. Inviarlo a uno sviluppatore, insieme a una descrizione di ciò che hai fatto per provocare l'errore." +prompt_crash_dump_saved = "File di dump salvato in '{}'. Si prega di inviarlo a {} , insieme a una descrizione di cosa è stato fatto per generare l'errore." prompt_fallback_to_opengl = "Se questo crash persiste, il passaggio al rendering OpenGL potrebbe aiutare a risolverlo. Vuoi provare ora?" \ No newline at end of file diff --git a/assets/scripts/localization/jp/texts/prompts.txt b/assets/scripts/localization/jp/texts/prompts.txt index a38ad0e31..65f5fb90c 100644 --- a/assets/scripts/localization/jp/texts/prompts.txt +++ b/assets/scripts/localization/jp/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "はい" prompt_crash = "プログラムに致命的なエラーが発生しました。診断ファイルを保存しますか?このファイルには、クラッシュ時のシステム情報やゲームの状態が含まれており、開発者が問題を解決するのに役立てることができます。" prompt_crash_dump_archive_failed = "ダンプファイルの保存に失敗しました: {}" prompt_crash_dump_generation_failed = "'{}' にダンプファイルを保存できませんでした: エラーコード {}" -prompt_crash_dump_saved = "'{}' にダンプファイルを保存しました。このファイルと、エラーが発生するまでに行った操作の説明を開発者に送ってください。" +prompt_crash_dump_saved = "'{}' にダンプファイルを保存しました。エラーが発生した際に行った手順の説明と共に、{} までお送りください。" prompt_fallback_to_opengl = "このクラッシュが続く場合、OpenGL レンダリングに切り替えることで解決する可能性があります。今すぐ試してみますか?" \ No newline at end of file diff --git a/assets/scripts/localization/pl/texts/prompts.txt b/assets/scripts/localization/pl/texts/prompts.txt index 66397da56..bb228e767 100644 --- a/assets/scripts/localization/pl/texts/prompts.txt +++ b/assets/scripts/localization/pl/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "Tak" prompt_crash = "W programie wystąpił krytyczny błąd. Czy chcesz zapisać plik diagnostyczny? Plik ten zawiera informacje o twoim systemie i stanie gry w momencie awarii i może zostać wykorzystany przez programistę do rozwiązania problemu." prompt_crash_dump_archive_failed = "Nie udało się zapisać pliku zrzutu: {}" prompt_crash_dump_generation_failed = "Nie udało się zapisać pliku zrzutu w '{}': Kod błędu {}" -prompt_crash_dump_saved = "Zapisano plik zrzutu w '{}'. Wyślij go do programisty wraz z opisem, co zrobiłeś, aby wywołać błąd." +prompt_crash_dump_saved = "Plik zrzutu został zapisany w '{}'. Proszę wysłać go na adres {} , wraz z opisem czynności wykonanych w celu wywołania błędu." prompt_fallback_to_opengl = "Jeśli ten błąd będzie się powtarzał, przełączenie na renderowanie OpenGL może pomóc go rozwiązać. Czy chcesz spróbować teraz?" \ No newline at end of file diff --git a/assets/scripts/localization/zh-cn/texts/prompts.txt b/assets/scripts/localization/zh-cn/texts/prompts.txt index 80f4ada98..bd833b387 100644 --- a/assets/scripts/localization/zh-cn/texts/prompts.txt +++ b/assets/scripts/localization/zh-cn/texts/prompts.txt @@ -10,5 +10,5 @@ prompt_button_yes = "是" prompt_crash = "程序发生了致命错误。是否要保存诊断文件?该文件包含您的系统信息以及游戏崩溃时的状态,可供开发人员用于修复潜在问题。" prompt_crash_dump_archive_failed = "无法保存转储文件:{}" prompt_crash_dump_generation_failed = "无法保存转储文件到'{}':错误代码 {}" -prompt_crash_dump_saved = "转储文件已保存到'{}'。请将其与您触发错误时的操作说明一并发送给开发人员。" +prompt_crash_dump_saved = "已将转储文件保存到 '{}'。请将其发送至 {},并附上您触发错误时执行的操作说明。" prompt_fallback_to_opengl = "如果此崩溃持续发生,切换到 OpenGL 渲染可能有助于解决问题。您想立即尝试吗?" \ No newline at end of file diff --git a/core/shared/src/debug/mdump.cpp b/core/shared/src/debug/mdump.cpp index f9a522555..657311347 100644 --- a/core/shared/src/debug/mdump.cpp +++ b/core/shared/src/debug/mdump.cpp @@ -39,15 +39,16 @@ CrashHandler::CrashHandler(const std::string &appName) : m_appName {appName} #ifdef _WIN32 ::SetUnhandledExceptionFilter(TopLevelFilter); #else - signal(SIGSEGV, +[](int sig) { - if(!g_crashHandler) { - exit(1); - return; - } - g_crashHandler->m_sig = sig; - g_crashHandler->GenerateCrashDump(); - exit(1); - }); + signal( + SIGSEGV, +[](int sig) { + if(!g_crashHandler) { + exit(1); + return; + } + g_crashHandler->m_sig = sig; + g_crashHandler->GenerateCrashDump(); + exit(1); + }); #endif // Note: set_terminate handler is called before SetUnhandledExceptionFilter. // set_terminate allows us to retrieve the underlying message from the exception (if there was one) @@ -176,10 +177,10 @@ bool CrashHandler::GenerateCrashDump() const symbols = backtrace_symbols(array, size); std::optional backtraceStr {}; - if (symbols != nullptr) { + if(symbols != nullptr) { snprintf(buffer, sizeof(buffer), "Error: signal %d:\n", m_sig); - for (size_t i = 0; i < size; i++) { + for(size_t i = 0; i < size; i++) { strncat(buffer, symbols[i], sizeof(buffer) - strlen(buffer) - 1); strncat(buffer, "\n", sizeof(buffer) - strlen(buffer) - 1); } @@ -224,14 +225,14 @@ bool CrashHandler::GenerateCrashDump() const else zipFile->AddFile("minidump_generation_error.txt", dumpErr); #else - if (backtraceStr) + if(backtraceStr) zipFile->AddFile("backtrace.txt", *backtraceStr); else zipFile->AddFile("backtrace_generation_error.txt", "Failed to generate backtrace symbols"); #endif zipFile = nullptr; - szResult = Locale::GetText("prompt_crash_dump_saved", std::vector {zipFileName}); + szResult = Locale::GetText("prompt_crash_dump_saved", std::vector {zipFileName, "crashdumps@pragma-engine.com"}); auto absPath = util::Path::CreatePath(util::get_program_path()) + zipFileName; util::open_path_in_explorer(std::string {absPath.GetPath()}, std::string {absPath.GetFileName()}); From cb6cd738da31287a33478dcbc4d896d1b5ba110a Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 02:58:55 +0100 Subject: [PATCH 02/64] feat(shader_graph): add ui elements --- .../lua/gui/shader_graph/node.lua | 94 ++++++++++++++ .../lua/gui/shader_graph/node_socket.lua | 35 ++++++ .../lua/gui/shader_graph/shader_graph.lua | 116 ++++++++++++++++++ 3 files changed, 245 insertions(+) create mode 100644 assets/addons/shader_graph/lua/gui/shader_graph/node.lua create mode 100644 assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua create mode 100644 assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/node.lua b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua new file mode 100644 index 000000000..847b8b6b4 --- /dev/null +++ b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua @@ -0,0 +1,94 @@ +--[[ + Copyright (C) 2024 Silverlan + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +]] + +local Element = util.register_class("gui.GraphNode", gui.Base) +function Element:OnInitialize() + gui.Base.OnInitialize(self) + + self:SetSize(128, 128) + + local bg = gui.create("WIRect", self, 0, 0, self:GetWidth(), self:GetHeight(), 0, 0, 1, 1) + self.m_bg = bg + + local box = gui.create("WIVBox", self, 0, 0, self:GetWidth(), self:GetHeight()) + box:SetName("global_container") + box:SetFixedWidth(true) + + local outputControls = gui.create("WIPFMControlsMenu", box, 0, 0, box:GetWidth(), box:GetHeight()) + outputControls:SetAutoFillContentsToHeight(false) + outputControls:SetFixedHeight(false) + self.m_outputControls = outputControls + + local inputControls = + gui.create("WIPFMControlsMenu", box, 0, outputControls:GetBottom(), box:GetWidth(), box:GetHeight()) + inputControls:SetAutoFillContentsToHeight(false) + inputControls:SetFixedHeight(false) + inputControls:AddCallback("SetSize", function() + self:SetHeight(inputControls:GetBottom()) + end) + self.m_inputControls = inputControls + + self.m_inputs = {} + self.m_outputs = {} + + outputControls:SetHeight(0) + inputControls:SetHeight(0) + outputControls:ResetControls() + inputControls:ResetControls() +end +function Element:SetNode(name) + self.m_node = name +end +function Element:GetNode() + return self.m_node +end +function Element:AddControl(socketType, title, id) + local ctrlMenu = (socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT) and self.m_inputControls + or self.m_outputControls + local elCtrl = ctrlMenu:AddSliderControl(title, id, 0.01, 0.0, 0.1, function(el, value) + -- + end, 0.001) + local el = gui.create("WIGraphNodeSocket", elCtrl) + el:SetSocket(self, id, socketType) + el:SetMouseInputEnabled(true) + el:AddCallback("OnMouseEvent", function(el, button, state, mods) + if button == input.MOUSE_BUTTON_LEFT and state == input.STATE_PRESS then + self:CallCallbacks("OnSocketClicked", el, socketType, id) + return util.EVENT_REPLY_HANDLED + end + end) + local t = (socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT) and self.m_inputs or self.m_outputs + t[id] = { + socketElement = el, + controlElement = elCtrl, + } + return el +end +function Element:GetSocket(socketType, name) + local t = (socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT) and self.m_inputs or self.m_outputs + if t[name] == nil then + return + end + return t[name].socketElement +end +function Element:GetInputSocket(name) + return self:GetSocket(gui.GraphNodeSocket.SOCKET_TYPE_INPUT, name) +end +function Element:GetOutputSocket(name) + return self:GetSocket(gui.GraphNodeSocket.SOCKET_TYPE_OUTPUT, name) +end +function Element:AddInput(name) + return self:AddControl(gui.GraphNodeSocket.SOCKET_TYPE_INPUT, name, name) +end +function Element:AddOutput(name) + local elSocket = self:AddControl(gui.GraphNodeSocket.SOCKET_TYPE_OUTPUT, name, name) + elSocket:SetX(self:GetWidth() - elSocket:GetWidth()) + elSocket:SetAnchor(1, 0, 1, 0) + return elSocket +end +gui.register("WIGraphNode", Element) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua b/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua new file mode 100644 index 000000000..20f6eb0b1 --- /dev/null +++ b/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua @@ -0,0 +1,35 @@ +--[[ + Copyright (C) 2024 Silverlan + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +]] + +local Element = util.register_class("gui.GraphNodeSocket", gui.Base) +Element.SOCKET_TYPE_INPUT = 0 +Element.SOCKET_TYPE_OUTPUT = 1 +function Element:OnInitialize() + gui.Base.OnInitialize(self) + + self:SetSize(16, 16) + + local bg = gui.create("WIRect", self, 0, 0, self:GetWidth(), self:GetHeight(), 0, 0, 1, 1) + bg:SetColor(Color.Red) + self.m_bg = bg +end +function Element:SetSocket(node, socket, socketType) + self.m_node = node + self.m_socket = socket + self.m_socketType = socketType +end +function Element:GetNode() + return self.m_node +end +function Element:GetSocket() + return self.m_socket +end +function Element:GetSocketType() + return self.m_socketType +end +gui.register("WIGraphNodeSocket", Element) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua new file mode 100644 index 000000000..865f94af5 --- /dev/null +++ b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua @@ -0,0 +1,116 @@ +--[[ + Copyright (C) 2024 Silverlan + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +]] + +include("/gui/pfm/tutorials/element_connector_line.lua") +include("node.lua") +include("node_socket.lua") + +local Element = util.register_class("gui.ShaderGraph", gui.Base) +function Element:OnInitialize() + gui.Base.OnInitialize(self) + + self.m_nameToElement = {} + self.m_nodeElements = {} + self.m_linkElements = {} + self:SetSize(1280, 1024) + self:TrapFocus() + self:RequestFocus() +end +function Element:SetGraph(graph) + self.m_graph = graph + + local nodes = self.m_graph:GetNodes() + for _, graphNode in ipairs(nodes) do + self:AddNode(graphNode) + end + + self:InitializeLinks() +end +function Element:InitializeLinks() + self:ClearLinks() + local links = {} + local nodes = self.m_graph:GetNodes() + for _, graphNode in ipairs(nodes) do + for _, input in ipairs(graphNode:GetInputs()) do + local socket = input:GetSocket() + local output = input:GetLinkedOutput() + if output ~= nil then + table.insert(links, { + inputNode = graphNode, + input = socket.name, + outputNode = output:GetNode(), + output = output:GetSocket().name, + }) + end + end + end + + for _, link in ipairs(links) do + local elOutput = self.m_nameToElement[link.outputNode:GetName()] + local elInput = self.m_nameToElement[link.inputNode:GetName()] + local elOutputSocket = elOutput:GetOutputSocket(link.output) + local elInputSocket = elInput:GetInputSocket(link.input) + if util.is_valid(elOutputSocket) and util.is_valid(elInputSocket) then + self:AddLink(elOutputSocket, elInputSocket) + end + end +end +function Element:ClearLinks() + util.remove(self.m_linkElements) + self.m_linkElements = {} +end +function Element:AddLink(elOutputSocket, elInputSocket) + local l = gui.create("WIElementConnectorLine", self) + l:SetSize(self:GetSize()) + l:SetAnchor(0, 0, 1, 1) + l:Setup(elOutputSocket, elInputSocket) + table.insert(self.m_linkElements, l) +end +function Element:AddNode(graphNode) + local node = graphNode:GetNode() + local elNode = gui.create("WIGraphNode", self) + elNode:SetNode(graphNode:GetName()) + elNode:SetX(#self.m_nodeElements * 200) + for _, output in ipairs(graphNode:GetOutputs()) do + local socket = output:GetSocket() + local elOutput = elNode:AddOutput(socket.name) + end + for _, input in ipairs(graphNode:GetInputs()) do + local socket = input:GetSocket() + local elInput = elNode:AddInput(socket.name) + end + --x = elNode:GetRight() + 80 + + elNode:AddCallback("OnSocketClicked", function(elNode, elSocket, socketType, id) + if util.is_valid(self.m_outSocket) == false then + self.m_outSocket = elSocket + else + local outSocket = self.m_outSocket + local inSocket = elSocket + local outNode = outSocket:GetNode():GetNode() + local outSocket = outSocket:GetSocket() + local inNode = inSocket:GetNode():GetNode() + local inSocket = inSocket:GetSocket() + self.m_outSocket = nil + + if outNode == inNode then + if outSocket == inSocket then + self.m_graph:GetNode(outNode):Disconnect(outSocket) + self:InitializeLinks() + return + end + end + self.m_graph:GetNode(outNode):Link(outSocket, self.m_graph:GetNode(inNode), inSocket) + self:InitializeLinks() + end + end) + + table.insert(self.m_nodeElements, elNode) + self.m_nameToElement[graphNode:GetName()] = elNode +end +gui.register("WIShaderGraph", Element) From bc9d13629b9444247d16aa73ce51e157885b04ae Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 10:31:32 +0100 Subject: [PATCH 03/64] feat(lua): add gui.Frame:SetDetachButtonEnabled --- core/client/src/lua/classes/c_lwibase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/client/src/lua/classes/c_lwibase.cpp b/core/client/src/lua/classes/c_lwibase.cpp index 5745abb7d..2469ba03a 100644 --- a/core/client/src/lua/classes/c_lwibase.cpp +++ b/core/client/src/lua/classes/c_lwibase.cpp @@ -821,6 +821,7 @@ void Lua::WIFrame::register_class(luabind::class_<::WIFrame, luabind::bases<::WI classDef.def("SetTitle", &::WIFrame::SetTitle); classDef.def("GetTitle", &::WIFrame::GetTitle); classDef.def("SetCloseButtonEnabled", &::WIFrame::SetCloseButtonEnabled); + classDef.def("SetDetachButtonEnabled", &::WIFrame::SetDetachButtonEnabled); } void Lua::WIDropDownMenu::register_class(luabind::class_<::WIDropDownMenu, luabind::bases<::WITextEntry, ::WIBase>> &classDef) From 2f0f0cce366742203cd2b1fb207ac175e0658930 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 10:32:29 +0100 Subject: [PATCH 04/64] build(cmake): add shadergraph dependency --- build_scripts/scripts/external_libs.py | 1 + core/client/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 1659cf021..b57efe35f 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -32,6 +32,7 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","a0d4f5847114cfb2db07721252ffc7bbf1da1434") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") diff --git a/core/client/CMakeLists.txt b/core/client/CMakeLists.txt index 372a6d896..1749dce99 100644 --- a/core/client/CMakeLists.txt +++ b/core/client/CMakeLists.txt @@ -15,6 +15,7 @@ pr_add_dependency(${PROJ_NAME} util_source_script TARGET) pr_add_dependency(${PROJ_NAME} util_zip TARGET) pr_add_dependency(${PROJ_NAME} util_timeline_scene TARGET PUBLIC) pr_add_dependency(${PROJ_NAME} util_bsp TARGET) +pr_add_dependency(${PROJ_NAME} util_shadergraph TARGET) pr_add_dependency(${PROJ_NAME} rectangle_bin_pack TARGET) pr_add_dependency(${PROJ_NAME} Recast TARGET) From 235a6a2911b3993b210ae1d5840ea43487fa2590 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 10:33:07 +0100 Subject: [PATCH 05/64] feat(shader_graph): add ui options for adding and removing nodes --- .../lua/gui/shader_graph/shader_graph.lua | 90 ++++++++++++++++--- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua index 865f94af5..089b4ca89 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua @@ -14,12 +14,28 @@ local Element = util.register_class("gui.ShaderGraph", gui.Base) function Element:OnInitialize() gui.Base.OnInitialize(self) - self.m_nameToElement = {} - self.m_nodeElements = {} + self.m_nameToElementData = {} + self.m_nodeData = {} self.m_linkElements = {} self:SetSize(1280, 1024) - self:TrapFocus() - self:RequestFocus() + + self:SetMouseInputEnabled(true) +end +function Element:MouseCallback(button, state, mods) + if button == input.MOUSE_BUTTON_RIGHT and state == input.STATE_PRESS then + local pContext = gui.open_context_menu(self) + if util.is_valid(pContext) then + pContext:AddItem("Add Node", function() + local graphNode = self.m_graph:AddNode("math") + if graphNode ~= nil then + self:AddNode(graphNode) + self:InitializeLinks() + end + end) + pContext:Update() + return util.EVENT_REPLY_HANDLED + end + end end function Element:SetGraph(graph) self.m_graph = graph @@ -51,8 +67,8 @@ function Element:InitializeLinks() end for _, link in ipairs(links) do - local elOutput = self.m_nameToElement[link.outputNode:GetName()] - local elInput = self.m_nameToElement[link.inputNode:GetName()] + local elOutput = self.m_nameToElementData[link.outputNode:GetName()].nodeElement + local elInput = self.m_nameToElementData[link.inputNode:GetName()].nodeElement local elOutputSocket = elOutput:GetOutputSocket(link.output) local elInputSocket = elInput:GetInputSocket(link.input) if util.is_valid(elOutputSocket) and util.is_valid(elInputSocket) then @@ -71,11 +87,58 @@ function Element:AddLink(elOutputSocket, elInputSocket) l:Setup(elOutputSocket, elInputSocket) table.insert(self.m_linkElements, l) end +function Element:RemoveNode(name) + local t = self.m_nameToElementData[name] + if t == nil then + return + end + + util.remove(t.frame) + + for i, tOther in ipairs(self.m_nodeData) do + if tOther == t then + table.remove(self.m_nodeData, i) + break + end + end + self.m_nameToElementData[name] = nil + self:InitializeLinks() +end function Element:AddNode(graphNode) - local node = graphNode:GetNode() - local elNode = gui.create("WIGraphNode", self) + local name = graphNode:GetName() + local frame = gui.create("WIFrame", self) + frame:SetTitle(name) + frame:SetDetachButtonEnabled(false) + frame:SetSize(128, 128) + + frame:SetMouseInputEnabled(true) + frame:AddCallback("OnMouseEvent", function(el, button, state, mods) + if button == input.MOUSE_BUTTON_RIGHT and state == input.STATE_PRESS then + local pContext = gui.open_context_menu(self) + if util.is_valid(pContext) then + pContext:AddItem("Remove Node", function() + if self.m_graph:RemoveNode(name) then + time.create_simple_timer(0.0, function() + if self:IsValid() then + self:RemoveNode(name) + end + end) + end + end) + pContext:Update() + end + return util.EVENT_REPLY_HANDLED + end + end) + + local pDrag = frame:GetDragArea() + pDrag:SetHeight(31) + pDrag:SetAutoAlignToParent(true, false) + + local elNode = gui.create("WIGraphNode", frame) elNode:SetNode(graphNode:GetName()) - elNode:SetX(#self.m_nodeElements * 200) + elNode:SetY(31) + frame:SetX(#self.m_nodeData * 200) for _, output in ipairs(graphNode:GetOutputs()) do local socket = output:GetSocket() local elOutput = elNode:AddOutput(socket.name) @@ -110,7 +173,12 @@ function Element:AddNode(graphNode) end end) - table.insert(self.m_nodeElements, elNode) - self.m_nameToElement[graphNode:GetName()] = elNode + local t = { + frame = frame, + nodeElement = elNode, + graphNode = name, + } + table.insert(self.m_nodeData, t) + self.m_nameToElementData[graphNode:GetName()] = t end gui.register("WIShaderGraph", Element) From 5410336915c9ddc698d70f75cf854f24a8250177 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 10:34:42 +0100 Subject: [PATCH 06/64] feat(lua): add shader graph bindings --- core/client/src/lua/c_luaclass.cpp | 181 ++++++++++++++++++++--------- 1 file changed, 127 insertions(+), 54 deletions(-) diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index b82d5c90d..8e736414b 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -77,12 +77,16 @@ #include #include #include +#include #include #include +#include #include #include #include +import pragma.shadergraph; + extern DLLCLIENT CEngine *c_engine; extern DLLCLIENT ClientState *client; extern DLLCLIENT CGame *c_game; @@ -121,6 +125,100 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma val); } +static void register_shader_graph(luabind::module_ &modShader) +{ + auto defGraph = luabind::class_("ShaderGraph"); + defGraph.def("__tostring", +[](const pragma::shadergraph::Graph &graph) -> std::string { return "ShaderGraph"; }); + defGraph.def("AddNode", &pragma::shadergraph::Graph::AddNode); + defGraph.def("RemoveNode", &pragma::shadergraph::Graph::RemoveNode); + defGraph.def("GetNode", &pragma::shadergraph::Graph::GetNode); + defGraph.def( + "GetNodes", +[](lua_State *l, const pragma::shadergraph::Graph &graph) -> luabind::object { + auto t = luabind::newtable(l); + uint32_t idx = 1; + for(auto &node : graph.GetNodes()) + t[idx++] = node.get(); + return t; + }); + + auto defNode = luabind::class_("Node"); + defNode.def("GetType", &pragma::shadergraph::Node::GetType); + defNode.def( + "GetInputs", +[](lua_State *l, const pragma::shadergraph::Node &node) -> luabind::object { + auto t = luabind::newtable(l); + uint32_t idx = 1; + for(auto &socket : node.GetInputs()) + t[idx++] = &socket; + return t; + }); + defNode.def( + "GetOutputs", +[](lua_State *l, const pragma::shadergraph::Node &node) -> luabind::object { + auto t = luabind::newtable(l); + uint32_t idx = 1; + for(auto &socket : node.GetOutputs()) + t[idx++] = &socket; + return t; + }); + modShader[defNode]; + + auto defSocket = luabind::class_("Socket"); + defSocket.def_readonly("name", &pragma::shadergraph::Socket::name); + defSocket.def_readonly("type", &pragma::shadergraph::Socket::type); + modShader[defSocket]; + + auto defNodeRegistry = luabind::class_("NodeRegistry"); + defNodeRegistry.def("GetNode", &pragma::shadergraph::NodeRegistry::GetNode); + modShader[defNodeRegistry]; + + auto defGraphNode = luabind::class_("GraphNode"); + defGraphNode.def("GetName", &pragma::shadergraph::GraphNode::GetName); + defGraphNode.def("GetNode", +[](const pragma::shadergraph::GraphNode &graphNode) -> const pragma::shadergraph::Node * { return &graphNode.node; }); + defGraphNode.def("SetDisplayName", &pragma::shadergraph::GraphNode::SetDisplayName); + defGraphNode.def("GetDisplayName", &pragma::shadergraph::GraphNode::GetDisplayName); + defGraphNode.def("ClearInputValue", &pragma::shadergraph::GraphNode::ClearInputValue); + defGraphNode.def("CanLink", &pragma::shadergraph::GraphNode::CanLink); + defGraphNode.def("Link", &pragma::shadergraph::GraphNode::Link); + defGraphNode.def("Disconnect", static_cast(&pragma::shadergraph::GraphNode::Disconnect)); + defGraphNode.def("IsOutputLinked", &pragma::shadergraph::GraphNode::IsOutputLinked); + defGraphNode.def("FindOutputIndex", &pragma::shadergraph::GraphNode::FindOutputIndex); + defGraphNode.def("FindInputIndex", &pragma::shadergraph::GraphNode::FindInputIndex); + defGraphNode.def( + "GetInputs", +[](lua_State *l, const pragma::shadergraph::GraphNode &graphNode) -> luabind::object { + auto t = luabind::newtable(l); + uint32_t idx = 1; + for(auto &input : graphNode.inputs) + t[idx++] = &input; + return t; + }); + defGraphNode.def( + "GetOutputs", +[](lua_State *l, const pragma::shadergraph::GraphNode &graphNode) -> luabind::object { + auto t = luabind::newtable(l); + uint32_t idx = 1; + for(auto &output : graphNode.outputs) + t[idx++] = &output; + return t; + }); + modShader[defGraphNode]; + + auto defInputSocket = luabind::class_("InputSocket"); + defInputSocket.def("GetSocket", +[](const pragma::shadergraph::InputSocket &inputSocket) -> const pragma::shadergraph ::Socket * { return &inputSocket.GetSocket(); }); + defInputSocket.def("GetNode", +[](const pragma::shadergraph::InputSocket &inputSocket) -> pragma::shadergraph ::GraphNode * { return inputSocket.parent; }); + defInputSocket.def("GetLinkedOutput", +[](const pragma::shadergraph::InputSocket &inputSocket) -> pragma::shadergraph ::OutputSocket * { return inputSocket.link; }); + defInputSocket.def("ClearValue", &pragma::shadergraph::InputSocket::ClearValue); + defInputSocket.def("HasValue", &pragma::shadergraph::InputSocket::HasValue); + defInputSocket.def_readonly("socketIndex", &pragma::shadergraph::InputSocket::inputIndex); + modShader[defInputSocket]; + + auto defOutputSocket = luabind::class_("OutputSocket"); + defOutputSocket.def("GetSocket", +[](const pragma::shadergraph::OutputSocket &outputSocket) -> const pragma::shadergraph ::Socket * { return &outputSocket.GetSocket(); }); + defOutputSocket.def("GetNode", +[](const pragma::shadergraph::OutputSocket &outputSocket) -> pragma::shadergraph ::GraphNode * { return outputSocket.parent; }); + defOutputSocket.def("GetLinkedInputs", +[](const pragma::shadergraph::OutputSocket &outputSocket) -> std::vector { return outputSocket.links; }); + defOutputSocket.def_readonly("socketIndex", &pragma::shadergraph::OutputSocket::outputIndex); + modShader[defOutputSocket]; + + modShader[defGraph]; +} + void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) { auto &modEngine = lua.RegisterLibrary("engine"); @@ -337,12 +435,9 @@ 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("__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; @@ -373,12 +468,9 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) }); defProp.def_readonly("type", &pragma::rendering::shader_material::Property::type); defProp.def_readonly("propertyFlags", &pragma::rendering::shader_material::Property::propertyFlags); - 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.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.property( "minValue", +[](lua_State *l, const pragma::rendering::shader_material::Property &prop) -> luabind::object { if(!prop.range) @@ -419,10 +511,8 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) ss << "[" << tex.name << "]"; return ss.str(); }); - defTex.property( - "name", +[](const pragma::rendering::shader_material::Texture &tex) -> std::string { return tex.name; }); - defTex.property( - "specializationType", +[](const pragma::rendering::shader_material::Texture &tex) -> std::optional { return tex.specializationType ? *tex.specializationType : std::optional {}; }); + defTex.property("name", +[](const pragma::rendering::shader_material::Texture &tex) -> std::string { return tex.name; }); + defTex.property("specializationType", +[](const pragma::rendering::shader_material::Texture &tex) -> std::optional { return tex.specializationType ? *tex.specializationType : std::optional {}; }); 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); @@ -434,6 +524,8 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) auto defMatData = luabind::class_("ShaderMaterialData"); modShader[defMatData]; + register_shader_graph(modShader); + auto defShader = luabind::class_("Shader"); defShader.def( "GetWrapper", +[](lua_State *l, prosper::Shader &shader) -> luabind::object { @@ -445,15 +537,11 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) defShader.def( "RecordBindDescriptorSet", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::DescriptorSet &ds, uint32_t firstSet, luabind::object dynamicOffsets) { Lua::Shader::RecordBindDescriptorSet(l, shader, bindState, ds, firstSet, dynamicOffsets, 5); }); - defShader.def( - "RecordBindDescriptorSet", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::DescriptorSet &ds, uint32_t firstSet) { Lua::Shader::RecordBindDescriptorSet(l, shader, bindState, ds, firstSet, {}); }); - defShader.def( - "RecordBindDescriptorSet", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::DescriptorSet &ds) { Lua::Shader::RecordBindDescriptorSet(l, shader, bindState, ds, 0u, {}); }); + defShader.def("RecordBindDescriptorSet", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::DescriptorSet &ds, uint32_t firstSet) { Lua::Shader::RecordBindDescriptorSet(l, shader, bindState, ds, firstSet, {}); }); + defShader.def("RecordBindDescriptorSet", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::DescriptorSet &ds) { Lua::Shader::RecordBindDescriptorSet(l, shader, bindState, ds, 0u, {}); }); defShader.def("RecordBindDescriptorSets", &Lua::Shader::RecordBindDescriptorSets); - defShader.def( - "RecordBindDescriptorSets", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, luabind::object descSets, uint32_t firstSet) { Lua::Shader::RecordBindDescriptorSets(l, shader, bindState, descSets, firstSet, {}); }); - defShader.def( - "RecordBindDescriptorSets", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, luabind::object descSets) { Lua::Shader::RecordBindDescriptorSets(l, shader, bindState, descSets, 0u, {}); }); + defShader.def("RecordBindDescriptorSets", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, luabind::object descSets, uint32_t firstSet) { Lua::Shader::RecordBindDescriptorSets(l, shader, bindState, descSets, firstSet, {}); }); + defShader.def("RecordBindDescriptorSets", +[](lua_State *l, prosper::Shader &shader, prosper::ShaderBindState &bindState, luabind::object descSets) { Lua::Shader::RecordBindDescriptorSets(l, shader, bindState, descSets, 0u, {}); }); defShader.def( "RecordBindDescriptorSet", +[](lua_State *l, prosper::Shader &shader, prosper::util::PreparedCommandBuffer &pcb, Lua::Vulkan::DescriptorSet &ds, uint32_t firstSet, luabind::object dynamicOffsets) { Lua::Shader::RecordBindDescriptorSet(l, shader, pcb, ds, firstSet, dynamicOffsets, 5); }); @@ -484,35 +572,29 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) defShaderGraphics.def("RecordBindVertexBuffer", &Lua::Shader::Graphics::RecordBindVertexBuffer); defShaderGraphics.def( "RecordBindVertexBuffer", +[](lua_State *l, prosper::ShaderGraphics &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::Buffer &buffer, uint32_t startBinding) { Lua::Shader::Graphics::RecordBindVertexBuffer(l, shader, bindState, buffer, startBinding, 0u); }); - defShaderGraphics.def( - "RecordBindVertexBuffer", +[](lua_State *l, prosper::ShaderGraphics &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::Buffer &buffer) { Lua::Shader::Graphics::RecordBindVertexBuffer(l, shader, bindState, buffer, 0u, 0u); }); + defShaderGraphics.def("RecordBindVertexBuffer", +[](lua_State *l, prosper::ShaderGraphics &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::Buffer &buffer) { Lua::Shader::Graphics::RecordBindVertexBuffer(l, shader, bindState, buffer, 0u, 0u); }); defShaderGraphics.def("RecordBindVertexBuffers", &Lua::Shader::Graphics::RecordBindVertexBuffers); defShaderGraphics.def( "RecordBindVertexBuffers", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, luabind::object buffers, uint32_t startBinding) { Lua::Shader::Graphics::RecordBindVertexBuffers(l, shader, recordTarget, buffers, startBinding, {}); }); - defShaderGraphics.def( - "RecordBindVertexBuffers", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, luabind::object buffers) { Lua::Shader::Graphics::RecordBindVertexBuffers(l, shader, recordTarget, buffers, 0u, {}); }); + defShaderGraphics.def("RecordBindVertexBuffers", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, luabind::object buffers) { Lua::Shader::Graphics::RecordBindVertexBuffers(l, shader, recordTarget, buffers, 0u, {}); }); defShaderGraphics.def("RecordBindIndexBuffer", &Lua::Shader::Graphics::RecordBindIndexBuffer); defShaderGraphics.def( "RecordBindIndexBuffer", +[](lua_State *l, prosper::ShaderGraphics &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::Buffer &indexBuffer, uint32_t indexType) { Lua::Shader::Graphics::RecordBindIndexBuffer(l, shader, bindState, indexBuffer, indexType, 0u); }); defShaderGraphics.def("RecordDraw", static_cast(&Lua::Shader::Graphics::RecordDraw)); defShaderGraphics.def( "RecordDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t vertCount, uint32_t instanceCount, uint32_t firstVertex) { Lua::Shader::Graphics::RecordDraw(l, shader, recordTarget, vertCount, instanceCount, firstVertex, 0u); }); - defShaderGraphics.def( - "RecordDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t vertCount, uint32_t instanceCount) { Lua::Shader::Graphics::RecordDraw(l, shader, recordTarget, vertCount, instanceCount, 0u, 0u); }); - defShaderGraphics.def( - "RecordDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t vertCount) { Lua::Shader::Graphics::RecordDraw(l, shader, recordTarget, vertCount, 1u, 0u, 0u); }); + defShaderGraphics.def("RecordDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t vertCount, uint32_t instanceCount) { Lua::Shader::Graphics::RecordDraw(l, shader, recordTarget, vertCount, instanceCount, 0u, 0u); }); + defShaderGraphics.def("RecordDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t vertCount) { Lua::Shader::Graphics::RecordDraw(l, shader, recordTarget, vertCount, 1u, 0u, 0u); }); defShaderGraphics.def("RecordDrawIndexed", &Lua::Shader::Graphics::RecordDrawIndexed); defShaderGraphics.def( "RecordDrawIndexed", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex) { Lua::Shader::Graphics::RecordDrawIndexed(l, shader, recordTarget, indexCount, instanceCount, firstIndex, 0u); }); defShaderGraphics.def( "RecordDrawIndexed", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t indexCount, uint32_t instanceCount) { Lua::Shader::Graphics::RecordDrawIndexed(l, shader, recordTarget, indexCount, instanceCount, 0u, 0); }); - defShaderGraphics.def( - "RecordDrawIndexed", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t indexCount) { Lua::Shader::Graphics::RecordDrawIndexed(l, shader, recordTarget, indexCount, 1u, 0u, 0); }); + defShaderGraphics.def("RecordDrawIndexed", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget, uint32_t indexCount) { Lua::Shader::Graphics::RecordDrawIndexed(l, shader, recordTarget, indexCount, 1u, 0u, 0); }); defShaderGraphics.def("RecordBeginDraw", &Lua::Shader::Graphics::RecordBeginDraw); - defShaderGraphics.def( - "RecordBeginDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget) { Lua::Shader::Graphics::RecordBeginDraw(l, shader, recordTarget, 0u); }); + defShaderGraphics.def("RecordBeginDraw", +[](lua_State *l, prosper::ShaderGraphics &shader, const LuaShaderRecordTarget &recordTarget) { Lua::Shader::Graphics::RecordBeginDraw(l, shader, recordTarget, 0u); }); defShaderGraphics.def("RecordDraw", static_cast(&Lua::Shader::Graphics::RecordDraw)); defShaderGraphics.def("RecordEndDraw", &Lua::Shader::Graphics::RecordEndDraw); defShaderGraphics.def("GetRenderPass", static_cast(&Lua::Shader::Graphics::GetRenderPass)); @@ -564,15 +646,11 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) auto defShaderCompute = luabind::class_("Compute"); defShaderCompute.def("RecordDispatch", &Lua::Shader::Compute::RecordDispatch); - defShaderCompute.def( - "RecordDispatch", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState, uint32_t x, uint32_t y) { Lua::Shader::Compute::RecordDispatch(l, shader, bindState, x, y, 1u); }); - defShaderCompute.def( - "RecordDispatch", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState, uint32_t x) { Lua::Shader::Compute::RecordDispatch(l, shader, bindState, x, 1u, 1u); }); - defShaderCompute.def( - "RecordDispatch", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState) { Lua::Shader::Compute::RecordDispatch(l, shader, bindState, 1u, 1u, 1u); }); + defShaderCompute.def("RecordDispatch", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState, uint32_t x, uint32_t y) { Lua::Shader::Compute::RecordDispatch(l, shader, bindState, x, y, 1u); }); + defShaderCompute.def("RecordDispatch", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState, uint32_t x) { Lua::Shader::Compute::RecordDispatch(l, shader, bindState, x, 1u, 1u); }); + defShaderCompute.def("RecordDispatch", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState) { Lua::Shader::Compute::RecordDispatch(l, shader, bindState, 1u, 1u, 1u); }); defShaderCompute.def("RecordBeginCompute", &Lua::Shader::Compute::RecordBeginCompute); - defShaderCompute.def( - "RecordBeginCompute", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::CommandBuffer &hCommandBuffer) { Lua::Shader::Compute::RecordBeginCompute(l, shader, bindState, 0u); }); + defShaderCompute.def("RecordBeginCompute", +[](lua_State *l, prosper::ShaderCompute &shader, prosper::ShaderBindState &bindState, Lua::Vulkan::CommandBuffer &hCommandBuffer) { Lua::Shader::Compute::RecordBeginCompute(l, shader, bindState, 0u); }); defShaderCompute.def("RecordCompute", &Lua::Shader::Compute::RecordCompute); defShaderCompute.def("RecordEndCompute", &Lua::Shader::Compute::RecordEndCompute); modShader[defShaderCompute]; @@ -597,8 +675,7 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) modShader[defShaderFlipImage]; auto defShaderMergeImages = luabind::class_>("MergeImages"); - defShaderMergeImages.def( - "RecordDraw", +[](pragma::ShaderMergeImages &shader, Lua::Vulkan::CommandBuffer &hCommandBuffer, Lua::Vulkan::DescriptorSet &ds, Lua::Vulkan::DescriptorSet &ds2) { return shader.RecordDraw(hCommandBuffer, *ds.GetDescriptorSet(), *ds2.GetDescriptorSet()); }); + defShaderMergeImages.def("RecordDraw", +[](pragma::ShaderMergeImages &shader, Lua::Vulkan::CommandBuffer &hCommandBuffer, Lua::Vulkan::DescriptorSet &ds, Lua::Vulkan::DescriptorSet &ds2) { return shader.RecordDraw(hCommandBuffer, *ds.GetDescriptorSet(), *ds2.GetDescriptorSet()); }); modShader[defShaderMergeImages]; auto defShaderMergeIntoEquirect = luabind::class_>("Merge2dImageIntoEquirectangular"); @@ -871,14 +948,10 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) defShaderTextured3DBase.def("OnBindScene", &pragma::LuaShaderWrapperTextured3D::Lua_OnBindScene, &pragma::LuaShaderWrapperTextured3D::Lua_default_OnBindScene); defShaderTextured3DBase.def("OnBeginDraw", &pragma::LuaShaderWrapperTextured3D::Lua_OnBeginDraw, &pragma::LuaShaderWrapperTextured3D::Lua_default_OnBeginDraw); defShaderTextured3DBase.def("OnEndDraw", &pragma::LuaShaderWrapperTextured3D::Lua_OnEndDraw, &pragma::LuaShaderWrapperTextured3D::Lua_default_OnEndDraw); - defShaderTextured3DBase.def( - "IsDepthPrepassEnabled", +[](const pragma::LuaShaderWrapperTextured3D &shader) { return static_cast(shader.GetShader()).IsDepthPrepassEnabled(); }); - defShaderTextured3DBase.def( - "SetDepthPrepassEnabled", +[](pragma::LuaShaderWrapperTextured3D &shader, bool depthPrepassEnabled) { static_cast(shader.GetShader()).SetDepthPrepassEnabled(depthPrepassEnabled); }); - defShaderTextured3DBase.def( - "SetShaderMaterialName", +[](pragma::LuaShaderWrapperTextured3D &shader, const std::optional &shaderMatName) { static_cast(shader.GetShader()).SetShaderMaterialName(shaderMatName); }); - defShaderTextured3DBase.def( - "GetShaderMaterialName", +[](pragma::LuaShaderWrapperTextured3D &shader) -> std::optional { return static_cast(shader.GetShader()).GetShaderMaterialName(); }); + defShaderTextured3DBase.def("IsDepthPrepassEnabled", +[](const pragma::LuaShaderWrapperTextured3D &shader) { return static_cast(shader.GetShader()).IsDepthPrepassEnabled(); }); + defShaderTextured3DBase.def("SetDepthPrepassEnabled", +[](pragma::LuaShaderWrapperTextured3D &shader, bool depthPrepassEnabled) { static_cast(shader.GetShader()).SetDepthPrepassEnabled(depthPrepassEnabled); }); + defShaderTextured3DBase.def("SetShaderMaterialName", +[](pragma::LuaShaderWrapperTextured3D &shader, const std::optional &shaderMatName) { static_cast(shader.GetShader()).SetShaderMaterialName(shaderMatName); }); + defShaderTextured3DBase.def("GetShaderMaterialName", +[](pragma::LuaShaderWrapperTextured3D &shader) -> std::optional { return static_cast(shader.GetShader()).GetShaderMaterialName(); }); modShader[defShaderTextured3DBase]; auto defShaderPbr = luabind::class_>("BasePbr"); From e57f87b392d4cb109f4d1552aa9f8f53f23771a0 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 10:35:03 +0100 Subject: [PATCH 07/64] build: update submodules --- build_scripts/build.py | 4 ++-- build_scripts/scripts/external_libs.py | 2 +- build_scripts/scripts/modules.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index 8e2378664..77dea358b 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -820,7 +820,7 @@ def execbuildscript(filepath): if with_essential_client_modules: add_pragma_module( name="pr_prosper_vulkan", - commitSha="9071ef182a9286369922fab76232267208027a93", + commitSha="b629cd60523450274277cfd353bc78f9aed4c2fa", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) @@ -1136,7 +1136,7 @@ def download_addon(name,addonName,url,commitId=None): curDir = os.getcwd() if not skip_repository_updates: if with_pfm: - download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","e7680ee941c9696c5277c98e5b1b7a3530f3bc8e") + download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","b0cc0afcdb96aab8a5fe778fb20aef7eb5329115") download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","bd4844c06b9a42bacd17bb7e52d3381c3fd119e4") if with_vr: diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index b57efe35f..136e6ecc9 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","0e1415ded54800e826c78341a62c555ef53692c2") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","6e5238ef5bde5aafabdc6711d55a5a336c5aa13f") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 25f6bd632..74ec59947 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -12,6 +12,6 @@ get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","d73bf6dea11b1a79d5dc4715e224aa4cb15d0d48") -get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","9071ef182a9286369922fab76232267208027a93") +get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","b629cd60523450274277cfd353bc78f9aed4c2fa") os.chdir(curDir) From 426c01aa34b11356ddf9635af1771c80254132db Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 16:05:06 +0100 Subject: [PATCH 08/64] feat(lua): add util.FilePath, util.DirPath --- core/shared/src/lua/class.cpp | 122 ++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/core/shared/src/lua/class.cpp b/core/shared/src/lua/class.cpp index ee467024c..07f03db58 100644 --- a/core/shared/src/lua/class.cpp +++ b/core/shared/src/lua/class.cpp @@ -144,8 +144,7 @@ static void create_directory_change_listener(lua_State *l, const std::string &pa { Lua::CheckFunction(l, 2); try { - auto listener = std::make_shared( - path, [callback](const std::string &fileName) mutable { callback(fileName); }, flags); + auto listener = std::make_shared(path, [callback](const std::string &fileName) mutable { callback(fileName); }, flags); Lua::Push(l, listener); } catch(const std::runtime_error &err) { @@ -279,8 +278,7 @@ void pragma::lua::detail::register_lua_debug_tostring(lua_State *l, const std::t assert(crep); lua_rawgeti(l, LUA_REGISTRYINDEX, crep->metatable_ref()); auto o = luabind::object {luabind::from_stack(l, -1)}; - o["__debugger_tostring"] = luabind::make_function( - l, +[](const luabind::object &o) -> std::string { return tostring(o); }); + o["__debugger_tostring"] = luabind::make_function(l, +[](const luabind::object &o) -> std::string { return tostring(o); }); o["__name"] = crep->name(); lua_pop(l, 1); } @@ -311,6 +309,41 @@ static void add_task(lua_State *l, pragma::lua::LuaWorker &worker, const luabind static void add_task(pragma::lua::LuaWorker &worker, const std::shared_ptr> &subJob, float taskProgress) { worker.AddLuaTask(subJob, taskProgress); } +static int util_file_path(lua_State *l) +{ + int n = lua_gettop(l); /* number of arguments */ + int i; + std::vector args; + args.reserve(n); + for(i = 1; i <= n; i++) + args.push_back(Lua::CheckString(l, i)); + util::Path path {}; + if(args.size() > 1) { + for(size_t i = 0; i < (args.size() - 1); ++i) + path += util::Path::CreatePath(args[i]); + path += util::Path::CreateFile(args.back()); + } + else if(args.size() == 1) + path = util::Path::CreateFile(args.back()); + Lua::Push(l, path); + return 1; +} + +static int util_dir_path(lua_State *l) +{ + int n = lua_gettop(l); /* number of arguments */ + int i; + std::vector args; + args.reserve(n); + for(i = 1; i <= n; i++) + args.push_back(Lua::CheckString(l, i)); + util::Path path {}; + for(size_t i = 0; i < args.size(); ++i) + path += util::Path::CreatePath(args[i]); + Lua::Push(l, path); + return 1; +} + void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) { auto modString = luabind::module_(lua.GetState(), "string"); @@ -581,10 +614,8 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) })); defImageBuffer->def("SetPixelColor", static_cast(&uimg::ImageBuffer::SetPixelColor)); defImageBuffer->def("SetPixelColor", static_cast(&uimg::ImageBuffer::SetPixelColor)); - defImageBuffer->def( - "SetPixelColor", +[](lua_State *l, uimg::ImageBuffer &imgBuffer, uint32_t x, uint32_t y, const Color &color) { imgBuffer.SetPixelColor(x, y, color.ToVector4()); }); - defImageBuffer->def( - "SetPixelColor", +[](lua_State *l, uimg::ImageBuffer &imgBuffer, uimg::ImageBuffer::PixelIndex pixelIdx, const Color &color) { imgBuffer.SetPixelColor(pixelIdx, color.ToVector4()); }); + defImageBuffer->def("SetPixelColor", +[](lua_State *l, uimg::ImageBuffer &imgBuffer, uint32_t x, uint32_t y, const Color &color) { imgBuffer.SetPixelColor(x, y, color.ToVector4()); }); + defImageBuffer->def("SetPixelColor", +[](lua_State *l, uimg::ImageBuffer &imgBuffer, uimg::ImageBuffer::PixelIndex pixelIdx, const Color &color) { imgBuffer.SetPixelColor(pixelIdx, color.ToVector4()); }); defImageBuffer->def("CalcLuminance", static_cast([](lua_State *l, uimg::ImageBuffer &imgBuffer) { float avgLuminance, minLuminance, maxLuminance, logAvgLuminance; Vector3 avgIntensity; @@ -605,8 +636,7 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) return nullptr; return it->second; }); - defImageLayerSet->def( - "GetImages", +[](const uimg::ImageLayerSet &layerSet) { return layerSet.images; }); + defImageLayerSet->def("GetImages", +[](const uimg::ImageLayerSet &layerSet) { return layerSet.images; }); modUtil[*defImageLayerSet]; auto defWorker = luabind::class_("Worker"); @@ -615,44 +645,29 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) defWorker.def("GetResult", &pragma::lua::LuaWorker::GetResult); defWorker.def("SetResult", &pragma::lua::LuaWorker::SetResult); defWorker.def("SetStatus", &pragma::lua::LuaWorker::SetStatus); - defWorker.def( - "SetStatus", +[](pragma::lua::LuaWorker &worker, util::JobStatus jobStatus, const std::optional &resultMsg) { worker.SetStatus(jobStatus, resultMsg); }); - defWorker.def( - "SetStatus", +[](pragma::lua::LuaWorker &worker, util::JobStatus jobStatus) { worker.SetStatus(jobStatus); }); + defWorker.def("SetStatus", +[](pragma::lua::LuaWorker &worker, util::JobStatus jobStatus, const std::optional &resultMsg) { worker.SetStatus(jobStatus, resultMsg); }); + defWorker.def("SetStatus", +[](pragma::lua::LuaWorker &worker, util::JobStatus jobStatus) { worker.SetStatus(jobStatus); }); defWorker.def("UpdateProgress", &pragma::lua::LuaWorker::UpdateProgress); defWorker.def("AddTask", static_cast> &, float)>(&add_task)); defWorker.def("AddTask", static_cast(&add_task)); defWorker.def("SetProgressCallback", &pragma::lua::LuaWorker::SetProgressCallback); - defWorker.def( - "Cancel", +[](pragma::lua::LuaWorker &worker) { worker.Cancel(); }); - defWorker.def( - "IsComplete", +[](pragma::lua::LuaWorker &worker) { return worker.IsComplete(); }); - defWorker.def( - "IsPending", +[](pragma::lua::LuaWorker &worker) { return worker.IsPending(); }); - defWorker.def( - "IsCancelled", +[](pragma::lua::LuaWorker &worker) { return worker.IsCancelled(); }); - defWorker.def( - "IsSuccessful", +[](pragma::lua::LuaWorker &worker) { return worker.IsSuccessful(); }); - defWorker.def( - "IsThreadActive", +[](pragma::lua::LuaWorker &worker) { return worker.IsThreadActive(); }); - defWorker.def( - "GetProgress", +[](pragma::lua::LuaWorker &worker) { return worker.GetProgress(); }); - defWorker.def( - "GetStatus", +[](pragma::lua::LuaWorker &worker) { return worker.GetStatus(); }); - defWorker.def( - "GetResultMessage", +[](pragma::lua::LuaWorker &worker) { return worker.GetResultMessage(); }); - defWorker.def( - "GetResultCode", +[](pragma::lua::LuaWorker &worker) { return worker.GetResultCode(); }); - defWorker.def( - "IsValid", +[](pragma::lua::LuaWorker &worker) { return worker.IsValid(); }); + defWorker.def("Cancel", +[](pragma::lua::LuaWorker &worker) { worker.Cancel(); }); + defWorker.def("IsComplete", +[](pragma::lua::LuaWorker &worker) { return worker.IsComplete(); }); + defWorker.def("IsPending", +[](pragma::lua::LuaWorker &worker) { return worker.IsPending(); }); + defWorker.def("IsCancelled", +[](pragma::lua::LuaWorker &worker) { return worker.IsCancelled(); }); + defWorker.def("IsSuccessful", +[](pragma::lua::LuaWorker &worker) { return worker.IsSuccessful(); }); + defWorker.def("IsThreadActive", +[](pragma::lua::LuaWorker &worker) { return worker.IsThreadActive(); }); + defWorker.def("GetProgress", +[](pragma::lua::LuaWorker &worker) { return worker.GetProgress(); }); + defWorker.def("GetStatus", +[](pragma::lua::LuaWorker &worker) { return worker.GetStatus(); }); + defWorker.def("GetResultMessage", +[](pragma::lua::LuaWorker &worker) { return worker.GetResultMessage(); }); + defWorker.def("GetResultCode", +[](pragma::lua::LuaWorker &worker) { return worker.GetResultCode(); }); + defWorker.def("IsValid", +[](pragma::lua::LuaWorker &worker) { return worker.IsValid(); }); modUtil[defWorker]; auto defLuaParallelJob = luabind::class_, util::BaseParallelJob>("ParallelJob"); defLuaParallelJob.def("GetResult", static_cast &)>([](lua_State *l, util::ParallelJob &job) -> luabind::object { return job.GetResult(); })); - defLuaParallelJob.def( - "CallOnComplete", +[](util::ParallelJob &job, const Lua::func &onComplete) { static_cast(job.GetWorker()).CallOnComplete(onComplete); }); - defLuaParallelJob.def( - "SetProgressCallback", +[](util::ParallelJob &job, const Lua::func &func) { static_cast(job.GetWorker()).SetProgressCallback(func); }); + defLuaParallelJob.def("CallOnComplete", +[](util::ParallelJob &job, const Lua::func &onComplete) { static_cast(job.GetWorker()).CallOnComplete(onComplete); }); + defLuaParallelJob.def("SetProgressCallback", +[](util::ParallelJob &job, const Lua::func &func) { static_cast(job.GetWorker()).SetProgressCallback(func); }); modUtil[defLuaParallelJob]; modUtil[luabind::def( "create_parallel_job", +[](Game &game, const std::string &name, const Lua::func &func, const Lua::func &cancelFunc) -> std::shared_ptr> { @@ -669,8 +684,7 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) modUtil[defImgParallelJob]; auto defImgLayerSetParallelJob = luabind::class_, util::BaseParallelJob>("ParallelJobImageLayerSet"); - defImgLayerSetParallelJob.def( - "GetResult", +[](lua_State *l, util::ParallelJob &job) { Lua::Push(l, job.GetResult()); }); + defImgLayerSetParallelJob.def("GetResult", +[](lua_State *l, util::ParallelJob &job) { Lua::Push(l, job.GetResult()); }); defImgLayerSetParallelJob.def( "GetImage", +[](lua_State *l, util::ParallelJob &job) -> std::shared_ptr { if(job.GetResult().images.empty()) @@ -827,12 +841,9 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) Lua::PushString(l, *ext); })); defPath->def("RemoveFileExtension", static_cast([](lua_State *l, util::Path &p) { p.RemoveFileExtension(); })); - defPath->def( - "RemoveFileExtension", +[](lua_State *l, util::Path &p, const std::vector &extensions) { p.RemoveFileExtension(extensions); }); - defPath->def( - "MakeRelative", +[](lua_State *l, util::Path &p, util::Path &pOther) { return p.MakeRelative(pOther); }); - defPath->def( - "MakeRelative", +[](lua_State *l, util::Path &p, const std::string &other) { return p.MakeRelative(other); }); + defPath->def("RemoveFileExtension", +[](lua_State *l, util::Path &p, const std::vector &extensions) { p.RemoveFileExtension(extensions); }); + defPath->def("MakeRelative", +[](lua_State *l, util::Path &p, util::Path &pOther) { return p.MakeRelative(pOther); }); + defPath->def("MakeRelative", +[](lua_State *l, util::Path &p, const std::string &other) { return p.MakeRelative(other); }); defPath->def("GetComponentCount", &util::Path::GetComponentCount); defPath->def( "GetComponent", +[](util::Path &p, size_t offset) -> std::optional> { @@ -845,6 +856,9 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) defPath->def("IsEmpty", &util::Path::IsEmpty); modUtil[*defPath]; + lua_pushtablecfunction(lua.GetState(), "util", "FilePath", util_file_path); + lua_pushtablecfunction(lua.GetState(), "util", "DirPath", util_dir_path); + // Properties Lua::Property::register_classes(lua); @@ -1423,8 +1437,7 @@ void NetworkState::RegisterSharedLuaClasses(Lua::Interface &lua) defQuat->def("Distance", &uquat::distance); defQuat->def("GetConjugate", static_cast(&glm::conjugate)); defQuat->def("AlignToAxis", &uquat::align_rotation_to_axis); - defQuat->def( - "Equals", +[](const Quat &a, const Quat &b, float epsilon) { return umath::abs(a.x - b.x) <= epsilon && umath::abs(a.y - b.y) <= epsilon && umath::abs(a.z - b.z) <= epsilon && umath::abs(a.w - b.w) <= epsilon; }); + defQuat->def("Equals", +[](const Quat &a, const Quat &b, float epsilon) { return umath::abs(a.x - b.x) <= epsilon && umath::abs(a.y - b.y) <= epsilon && umath::abs(a.z - b.z) <= epsilon && umath::abs(a.w - b.w) <= epsilon; }); defQuat->def( "Equals", +[](const Quat &a, const Quat &b) { float epsilon = 0.001f; @@ -1524,10 +1537,8 @@ void Game::RegisterLuaClasses() {"COORDINATE_SPACE_VIEW", umath::to_integral(umath::CoordinateSpace::View)}, {"COORDINATE_SPACE_SCREEN", umath::to_integral(umath::CoordinateSpace::Screen)}, }); - modMath[luabind::def( - "coordinate_space_to_string", +[](umath::CoordinateSpace space) -> std::string { return std::string {magic_enum::enum_name(space)}; })]; - modMath[luabind::def( - "string_to_coordinate_space", +[](const std::string &space) -> std::optional { return magic_enum::enum_cast(space); })]; + modMath[luabind::def("coordinate_space_to_string", +[](umath::CoordinateSpace space) -> std::string { return std::string {magic_enum::enum_name(space)}; })]; + modMath[luabind::def("string_to_coordinate_space", +[](const std::string &space) -> std::optional { return magic_enum::enum_cast(space); })]; auto defPlane = luabind::class_("Plane"); defPlane.def(luabind::constructor()); @@ -1707,8 +1718,7 @@ void Game::RegisterLuaGameClasses(luabind::module_ &gameMod) return *s_entIterator; }, luabind::return_stl_iterator {})]; - modEnts[luabind::def( - "citerator", +[](lua_State *l, Lua::nil_type) -> LuaEntityComponentIterator & { return citerator(l, pragma::INVALID_COMPONENT_ID); }, luabind::return_stl_iterator {})]; + modEnts[luabind::def("citerator", +[](lua_State *l, Lua::nil_type) -> LuaEntityComponentIterator & { return citerator(l, pragma::INVALID_COMPONENT_ID); }, luabind::return_stl_iterator {})]; modEnts[luabind::def("citerator", static_cast(&citerator), luabind::return_stl_iterator {})]; modEnts[luabind::def("citerator", static_cast> &)>(&citerator), luabind::return_stl_iterator {})]; modEnts[luabind::def("citerator", static_cast &)>(&citerator), luabind::return_stl_iterator {})]; From 511217b74ff0343189d4162c53e557bfe88a1825 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 16:05:59 +0100 Subject: [PATCH 09/64] feat(shader_graph): add lua bindings --- core/client/src/lua/c_luaclass.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 8e736414b..1e1819622 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -126,9 +126,28 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma } static void register_shader_graph(luabind::module_ &modShader) +{ +static void register_shader_graph(lua_State *l, luabind::module_ &modShader) { auto defGraph = luabind::class_("ShaderGraph"); + defGraph.scope[luabind::def( + "load", +[](udm::AssetData &assetData, const std::shared_ptr &nodeReg) -> std::pair, std::optional> { + auto graph = std::make_shared(nodeReg); + std::string err; + auto data = assetData.GetData(); + auto result = graph->Load(data, err); + if(!result) + return {std::shared_ptr {}, std::optional {err}}; + return {graph, {}}; + })]; defGraph.def("__tostring", +[](const pragma::shadergraph::Graph &graph) -> std::string { return "ShaderGraph"; }); + defGraph.def( + "Save", +[](const pragma::shadergraph::Graph &graph, udm::AssetData &assetData) -> std::pair> { + std::string err; + if(!graph.Save(assetData, err)) + return {false, std::optional {}}; + return {true, err}; + }); defGraph.def("AddNode", &pragma::shadergraph::Graph::AddNode); defGraph.def("RemoveNode", &pragma::shadergraph::Graph::RemoveNode); defGraph.def("GetNode", &pragma::shadergraph::Graph::GetNode); @@ -217,6 +236,13 @@ static void register_shader_graph(luabind::module_ &modShader) modShader[defOutputSocket]; modShader[defGraph]; + + auto oClass = luabind::globals(l); + luabind::object oGraph = oClass["shader"]["ShaderGraph"]; + oGraph["EXTENSION_BINARY"] = pragma::shadergraph::Graph::EXTENSION_BINARY; + oGraph["EXTENSION_ASCII"] = pragma::shadergraph::Graph::EXTENSION_ASCII; + oGraph["PSG_IDENTIFIER"] = pragma::shadergraph::Graph::PSG_IDENTIFIER; + oGraph["PSG_VERSION"] = pragma::shadergraph::Graph::PSG_VERSION; } void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) @@ -524,7 +550,7 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) auto defMatData = luabind::class_("ShaderMaterialData"); modShader[defMatData]; - register_shader_graph(modShader); + register_shader_graph(lua.GetState(), modShader); auto defShader = luabind::class_("Shader"); defShader.def( From 3fbead9e24ee94bdb7e6d89f14e42926b95d07b7 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 16:06:44 +0100 Subject: [PATCH 10/64] feat(shader_graph): add ui options for saving/loading graph --- .../lua/gui/shader_graph/shader_graph.lua | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua index 089b4ca89..bb0ff88ee 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua @@ -25,6 +25,61 @@ function Element:MouseCallback(button, state, mods) if button == input.MOUSE_BUTTON_RIGHT and state == input.STATE_PRESS then local pContext = gui.open_context_menu(self) if util.is_valid(pContext) then + pContext:AddItem("Load Graph", function() + local pFileDialog = pfm.create_file_open_dialog(function(el, fileName) + if fileName == nil then + return + end + fileName = el:GetFilePath(false) + + local udmData, err = udm.load(fileName) + if udmData == false then + self:LogWarn("Failed to load shader graph file '" .. fileName .. "': " .. err) + return + end + + local reg = shader.get_test_node_register() -- TODO + local graph, err = shader.ShaderGraph.load(udmData:GetAssetData(), reg) + if graph == false then + self:LogWarn("Failed to load shader graph '" .. fileName .. "': " .. err) + return + end + self:LogInfo("Loaded shader graph '" .. fileName .. "'!") + self:SetGraph(graph) + end) + pFileDialog:SetRootPath("scripts/shader_data/graphs") + pFileDialog:SetExtensions({ shader.ShaderGraph.EXTENSION_ASCII, shader.ShaderGraph.EXTENSION_BINARY }) + pFileDialog:Update() + end) + pContext:AddItem("Save Graph", function() + local pFileDialog = pfm.create_file_save_dialog(function(el, fileName) + if fileName == nil then + return + end + + fileName = el:GetFilePath(false) + fileName = file.remove_file_extension( + fileName, + { shader.ShaderGraph.EXTENSION_ASCII, shader.ShaderGraph.EXTENSION_BINARY } + ) + fileName = fileName .. "." .. shader.ShaderGraph.EXTENSION_ASCII + local udmData = udm.create(shader.ShaderGraph.PSG_IDENTIFIER, shader.ShaderGraph.PSG_VERSION) + local res, err = self.m_graph:Save(udmData:GetAssetData()) + if res == false then + self:LogWarn("Failed to save shader graph: " .. err) + return + end + file.create_path(file.get_file_path(fileName)) + res, err = udmData:SaveAscii(fileName) + if res == false then + self:LogWarn("Failed to save shader graph as '" .. fileName .. "': " .. err) + return + end + self:LogInfo("Saved shader graph as '" .. fileName .. "'!") + end) + pFileDialog:SetRootPath("scripts/shader_data/graphs") + pFileDialog:Update() + end) pContext:AddItem("Add Node", function() local graphNode = self.m_graph:AddNode("math") if graphNode ~= nil then @@ -38,6 +93,13 @@ function Element:MouseCallback(button, state, mods) end end function Element:SetGraph(graph) + self:ClearLinks() + for _, t in ipairs(self.m_nodeData) do + util.remove(t.frame) + end + self.m_nodeData = {} + self.m_nameToElementData = {} + self.m_graph = graph local nodes = self.m_graph:GetNodes() @@ -109,6 +171,7 @@ function Element:AddNode(graphNode) local frame = gui.create("WIFrame", self) frame:SetTitle(name) frame:SetDetachButtonEnabled(false) + frame:SetCloseButtonEnabled(false) frame:SetSize(128, 128) frame:SetMouseInputEnabled(true) From 5cc778daae71169db5463b8cb0621f5c7f073d28 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 16:10:09 +0100 Subject: [PATCH 11/64] build: update submodule "util_shadergraph" --- build_scripts/scripts/external_libs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 136e6ecc9..5254b4692 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -32,7 +32,7 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") -get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","a0d4f5847114cfb2db07721252ffc7bbf1da1434") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","33b89dfa095b64414703de5bcf9a7f9cd87bcbf6") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") From f460ece2d3626ad0c0faf3a0e9130cc9e1c46230 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 18 Nov 2024 18:39:10 +0100 Subject: [PATCH 12/64] fix: build error --- core/client/src/lua/c_luaclass.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 1e1819622..7669fa0df 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -125,7 +125,6 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma val); } -static void register_shader_graph(luabind::module_ &modShader) { static void register_shader_graph(lua_State *l, luabind::module_ &modShader) { From 3ee5156391962f48e1c088750fcfb76e63c3fdae Mon Sep 17 00:00:00 2001 From: Silverlan Date: Tue, 19 Nov 2024 08:26:55 +0100 Subject: [PATCH 13/64] fix: build error --- core/client/src/lua/c_luaclass.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 7669fa0df..ded4ddc30 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -125,7 +125,6 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma val); } -{ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) { auto defGraph = luabind::class_("ShaderGraph"); From 65deba22b76ca2a6a7b417c4845d808846db5252 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 20:38:13 +0100 Subject: [PATCH 14/64] feat(shader): add math utility functions --- assets/shaders/math/math.glsl | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/assets/shaders/math/math.glsl b/assets/shaders/math/math.glsl index e41d0a9e9..1db72aaa2 100644 --- a/assets/shaders/math/math.glsl +++ b/assets/shaders/math/math.glsl @@ -24,6 +24,8 @@ #define MIN_UINT 0 #define MAX_UINT 4294967295 +#define FLT_EPSILON 0.00001 + float length_sqr(vec3 v) { return pow2(v.x) + pow2(v.y) + pow2(v.z); } float units_to_meters(float units) { return units * 0.025; } @@ -37,4 +39,44 @@ float atan2(in float y, in float x) float calc_luminance(vec3 color) { return 0.212671 * color.r + 0.71516 * color.g + 0.072169 * color.b; } +float wrap(float value, float max, float min) +{ + float range = max -min; + return (range != 0.0) ? value -(range *floor((value -min) /range)) : min; +} + +vec3 wrap(vec3 value, vec3 max, vec3 min) +{ + return vec3( + wrap(value.x, max.x, min.x), + wrap(value.y, max.y, min.y), + wrap(value.z, max.z, min.z) + ); +} + +float pingpong(float a, float b) +{ + return (b != 0.0) ? abs(fract((a -b) / (b *2.0)) *b *2.0 -b) : 0.0; +} + +float smoothmin(float a, float b, float k) +{ + if (k != 0.0) { + float h = max(k -abs(a -b), 0.0) /k; + return min(a, b) - h *h *h *k *(1.0 / 6.0); + } else + return min(a, b); +} + +float floored_modulo(float a, float b) +{ + return (b != 0.0) ? a -floor(a / b) *b : 0.0; +} + +vec3 project(vec3 v, vec3 v_proj) +{ + float len_squared = dot(v_proj, v_proj); + return (len_squared != 0.0) ? (dot(v, v_proj) /len_squared) *v_proj : vec3(0.0); +} + #endif From 321d99ede328ba621d50dac4556a23a600c8d2b2 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 20:39:46 +0100 Subject: [PATCH 15/64] feat(shader_graph): add shader graph module files --- assets/shaders/modules/camera.glsl | 1 + assets/shaders/modules/fog.glsl | 1 + assets/shaders/modules/lightmap.glsl | 1 + assets/shaders/modules/math.glsl | 11 +++++++++++ assets/shaders/modules/object.glsl | 1 + assets/shaders/modules/render_settings.glsl | 1 + assets/shaders/modules/time.glsl | 1 + 7 files changed, 17 insertions(+) create mode 100644 assets/shaders/modules/camera.glsl create mode 100644 assets/shaders/modules/fog.glsl create mode 100644 assets/shaders/modules/lightmap.glsl create mode 100644 assets/shaders/modules/math.glsl create mode 100644 assets/shaders/modules/object.glsl create mode 100644 assets/shaders/modules/render_settings.glsl create mode 100644 assets/shaders/modules/time.glsl diff --git a/assets/shaders/modules/camera.glsl b/assets/shaders/modules/camera.glsl new file mode 100644 index 000000000..c511315d8 --- /dev/null +++ b/assets/shaders/modules/camera.glsl @@ -0,0 +1 @@ +#include "/common/inputs/camera.glsl" diff --git a/assets/shaders/modules/fog.glsl b/assets/shaders/modules/fog.glsl new file mode 100644 index 000000000..99c7faa42 --- /dev/null +++ b/assets/shaders/modules/fog.glsl @@ -0,0 +1 @@ +#include "/common/inputs/fs_fog.glsl" diff --git a/assets/shaders/modules/lightmap.glsl b/assets/shaders/modules/lightmap.glsl new file mode 100644 index 000000000..32686a464 --- /dev/null +++ b/assets/shaders/modules/lightmap.glsl @@ -0,0 +1 @@ +#include "/common/inputs/fs_lightmap.glsl" diff --git a/assets/shaders/modules/math.glsl b/assets/shaders/modules/math.glsl new file mode 100644 index 000000000..e872e9426 --- /dev/null +++ b/assets/shaders/modules/math.glsl @@ -0,0 +1,11 @@ +#include "/math/camera.glsl" +#include "/math/depth_bias.glsl" +#include "/math/ease.glsl" +#include "/math/equirectangular.glsl" +#include "/math/geometry.glsl" +#include "/math/half_float.glsl" +#include "/math/intersection.glsl" +#include "/math/math.glsl" +#include "/math/matrix.glsl" +#include "/math/poisson_disk.glsl" +#include "/math/quaternion.glsl" diff --git a/assets/shaders/modules/object.glsl b/assets/shaders/modules/object.glsl new file mode 100644 index 000000000..266570539 --- /dev/null +++ b/assets/shaders/modules/object.glsl @@ -0,0 +1 @@ +#include "/common/inputs/entity.glsl" diff --git a/assets/shaders/modules/render_settings.glsl b/assets/shaders/modules/render_settings.glsl new file mode 100644 index 000000000..5591013f6 --- /dev/null +++ b/assets/shaders/modules/render_settings.glsl @@ -0,0 +1 @@ +#include "/common/inputs/render_settings.glsl" diff --git a/assets/shaders/modules/time.glsl b/assets/shaders/modules/time.glsl new file mode 100644 index 000000000..721e41f70 --- /dev/null +++ b/assets/shaders/modules/time.glsl @@ -0,0 +1 @@ +#include "/common/inputs/time.glsl" From e5dc5083d6ef54cfef3d5cac0e0c1b6bbbb3f026 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 20:57:41 +0100 Subject: [PATCH 16/64] feat: normalize file path --- assets/lua/gui/wifiledialog.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lua/gui/wifiledialog.lua b/assets/lua/gui/wifiledialog.lua index b4b8f59d9..94e55facd 100644 --- a/assets/lua/gui/wifiledialog.lua +++ b/assets/lua/gui/wifiledialog.lua @@ -171,7 +171,7 @@ function gui.WIFileDialog:GetFilePath(relativePath) if util.is_valid(self.m_pFileName) == false then return "" end - return path .. self.m_pFileName:GetText() + return util.FilePath(path, self.m_pFileName:GetText()):GetString() end function gui.WIFileDialog:SetType(type) self.m_type = type From 683dab0c837ae0388281b7fc7404bdb699307681 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 21:00:05 +0100 Subject: [PATCH 17/64] feat: add drag callbacks --- core/client/src/gui/witransformable.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/client/src/gui/witransformable.cpp b/core/client/src/gui/witransformable.cpp index d72b5936d..9aa95bf78 100644 --- a/core/client/src/gui/witransformable.cpp +++ b/core/client/src/gui/witransformable.cpp @@ -26,6 +26,8 @@ WITransformable::WITransformable() : WIBase() { RegisterCallback("OnClose"); RegisterCallback, bool>("TranslateTransformPosition"); + RegisterCallback("OnDragStart"); + RegisterCallback("OnDragEnd"); } WITransformable::~WITransformable() { @@ -129,6 +131,7 @@ void WITransformable::StartDrag() return; GetMousePos(&m_dragCursorOffset.x, &m_dragCursorOffset.y); umath::set_flag(m_stateFlags, StateFlags::Dragging, true); + CallCallbacks("OnDragStart"); } void WITransformable::OnVisibilityChanged(bool bVisible) { @@ -146,6 +149,7 @@ void WITransformable::EndDrag() return; umath::set_flag(m_stateFlags, StateFlags::Dragging, false); umath::set_flag(m_stateFlags, StateFlags::WasDragged); + CallCallbacks("OnDragEnd"); } void WITransformable::StartResizing() { @@ -234,8 +238,7 @@ void WITransformable::OnCursorMoved(int x, int y) return; const auto fValidateCursorOverlap = [this]() { auto &wgui = WGUI::GetInstance(); - auto *pElCursor = wgui.GetCursorGUIElement( - wgui.GetBaseElement(), [](WIBase *el) -> bool { return true; }, GetRootWindow()); + auto *pElCursor = wgui.GetCursorGUIElement(wgui.GetBaseElement(), [](WIBase *el) -> bool { return true; }, GetRootWindow()); if(pElCursor != nullptr && pElCursor != this && pElCursor->IsDescendantOf(this) == false) { SetResizeMode(ResizeMode::none); return false; From d2a07eb3cdbfc1aebf7f019d2907606b83b19e26 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 21:02:16 +0100 Subject: [PATCH 18/64] feat: move determine_udm_type to header --- .../include/pragma/lua/libraries/ludm.hpp | 1 + core/shared/src/lua/libraries/ludm.cpp | 176 +++++++----------- 2 files changed, 68 insertions(+), 109 deletions(-) diff --git a/core/shared/include/pragma/lua/libraries/ludm.hpp b/core/shared/include/pragma/lua/libraries/ludm.hpp index 271e55d3a..497024129 100644 --- a/core/shared/include/pragma/lua/libraries/ludm.hpp +++ b/core/shared/include/pragma/lua/libraries/ludm.hpp @@ -32,6 +32,7 @@ namespace Lua { DLLNETWORK void set_array_values(lua_State *l, ::udm::Array &a, luabind::tableT t, uint32_t tIdx); DLLNETWORK bool set_array_value(lua_State *l, ::udm::Array &a, int32_t idx, const luabind::object &o); DLLNETWORK void table_to_udm(const Lua::tb &t, ::udm::LinkedPropertyWrapper &udm); + DLLNETWORK ::udm::Type determine_udm_type(const luabind::object &val); DLLNETWORK luabind::object udm_to_value(lua_State *l, ::udm::LinkedPropertyWrapperArg udm); template T cast_object(const Lua::udm_ng &value) diff --git a/core/shared/src/lua/libraries/ludm.cpp b/core/shared/src/lua/libraries/ludm.cpp index 980695803..e9086c5c3 100644 --- a/core/shared/src/lua/libraries/ludm.cpp +++ b/core/shared/src/lua/libraries/ludm.cpp @@ -32,83 +32,83 @@ extern DLLNETWORK Engine *engine; Lua::udm::LuaUdmArrayIterator::LuaUdmArrayIterator(::udm::PropertyWrapper &prop) : m_property {&prop} {} template -static bool is_udm_type(luabind::object &val) +static bool is_udm_type(const luabind::object &val) { return luabind::object_cast_nothrow(val, static_cast(nullptr)) != nullptr; } -static udm::Type determine_udm_type(luabind::object &val) +::udm::Type Lua::udm::determine_udm_type(const luabind::object &val) { - auto t = luabind::type(val); - switch(t) { - case LUA_TNIL: - return udm::Type::Nil; - case LUA_TBOOLEAN: - return udm::Type::Boolean; - case LUA_TSTRING: - return udm::Type::String; - case LUA_TNUMBER: + auto type = static_cast(luabind::type(val)); + switch(type) { + case Lua::Type::Nil: + return ::udm::Type::Nil; + case Lua::Type::Bool: + return ::udm::Type::Boolean; + case Lua::Type::String: + return ::udm::Type::String; + case Lua::Type::Number: { auto v = luabind::object_cast(val); if(static_cast(v) == v) { if(v < 0.0) - return udm::Type::UInt32; - return udm::Type::Int32; + return ::udm::Type::UInt32; + return ::udm::Type::Int32; } - return udm::Type::Float; + return ::udm::Type::Float; } - case LUA_TUSERDATA: + case Lua::Type::UserData: break; default: - return udm::Type::Invalid; + return ::udm::Type::Invalid; } - if(is_udm_type(val)) - return udm::Type::Vector2; - if(is_udm_type(val)) - return udm::Type::Vector3; - if(is_udm_type(val)) - return udm::Type::Vector4; - if(is_udm_type(val)) - return udm::Type::Vector2i; - if(is_udm_type(val)) - return udm::Type::Vector3i; - if(is_udm_type(val)) - return udm::Type::Vector4i; - if(is_udm_type(val)) - return udm::Type::Quaternion; - if(is_udm_type(val)) - return udm::Type::EulerAngles; - if(is_udm_type(val)) - return udm::Type::Srgba; - if(is_udm_type(val)) - return udm::Type::HdrColor; - if(is_udm_type(val)) - return udm::Type::Transform; - if(is_udm_type(val)) - return udm::Type::ScaledTransform; - if(is_udm_type(val)) - return udm::Type::Mat4; - if(is_udm_type(val)) - return udm::Type::Mat3x4; - if(is_udm_type(val)) - return udm::Type::String; - if(is_udm_type(val)) - return udm::Type::Utf8String; - if(is_udm_type(val)) - return udm::Type::Blob; - if(is_udm_type(val)) - return udm::Type::BlobLz4; - if(is_udm_type(val)) - return udm::Type::Element; - if(is_udm_type(val)) - return udm::Type::Array; - if(is_udm_type(val)) - return udm::Type::ArrayLz4; - if(is_udm_type(val)) - return udm::Type::Reference; - if(is_udm_type(val)) - return udm::Type::Struct; - return udm::Type::Invalid; + if(is_udm_type<::udm::Vector2>(val)) + return ::udm::Type::Vector2; + if(is_udm_type<::udm::Vector3>(val)) + return ::udm::Type::Vector3; + if(is_udm_type<::udm::Vector4>(val)) + return ::udm::Type::Vector4; + if(is_udm_type<::udm::Vector2i>(val)) + return ::udm::Type::Vector2i; + if(is_udm_type<::udm::Vector3i>(val)) + return ::udm::Type::Vector3i; + if(is_udm_type<::udm::Vector4i>(val)) + return ::udm::Type::Vector4i; + if(is_udm_type<::udm::Quaternion>(val)) + return ::udm::Type::Quaternion; + if(is_udm_type<::udm::EulerAngles>(val)) + return ::udm::Type::EulerAngles; + if(is_udm_type<::udm::Srgba>(val)) + return ::udm::Type::Srgba; + if(is_udm_type<::udm::HdrColor>(val)) + return ::udm::Type::HdrColor; + if(is_udm_type<::udm::Transform>(val)) + return ::udm::Type::Transform; + if(is_udm_type<::udm::ScaledTransform>(val)) + return ::udm::Type::ScaledTransform; + if(is_udm_type<::udm::Mat4>(val)) + return ::udm::Type::Mat4; + if(is_udm_type<::udm::Mat3x4>(val)) + return ::udm::Type::Mat3x4; + if(is_udm_type<::udm::String>(val)) + return ::udm::Type::String; + if(is_udm_type<::udm::Utf8String>(val)) + return ::udm::Type::Utf8String; + if(is_udm_type<::udm::Blob>(val)) + return ::udm::Type::Blob; + if(is_udm_type<::udm::BlobLz4>(val)) + return ::udm::Type::BlobLz4; + if(is_udm_type<::udm::Element>(val)) + return ::udm::Type::Element; + if(is_udm_type<::udm::Array>(val)) + return ::udm::Type::Array; + if(is_udm_type<::udm::ArrayLz4>(val)) + return ::udm::Type::ArrayLz4; + if(is_udm_type<::udm::Reference>(val)) + return ::udm::Type::Reference; + if(is_udm_type<::udm::Struct>(val)) + return ::udm::Type::Struct; + return ::udm::Type::Invalid; } void Lua::udm::table_to_udm(const Lua::tb &t, ::udm::LinkedPropertyWrapper &udm) @@ -344,48 +344,6 @@ static Lua::var, ::udm::Data> create(lua_State *l, } } -static udm::Type determine_lua_object_udm_type(const luabind::object &o) -{ - auto type = static_cast(luabind::type(o)); - if(type == Lua::Type::Bool) - return udm::Type::Boolean; - if(type == Lua::Type::Number) - return udm::Type::Float; - if(type == Lua::Type::String) - return udm::Type::String; - - auto isType = [&o]() -> bool { return luabind::object_cast_nothrow(o, static_cast(nullptr)) != nullptr; }; - if(isType.template operator()()) - return udm::Type::Vector2; - if(isType.template operator()()) - return udm::Type::Vector3; - if(isType.template operator()()) - return udm::Type::Vector4; - if(isType.template operator()()) - return udm::Type::Quaternion; - if(isType.template operator()()) - return udm::Type::EulerAngles; - if(isType.template operator()()) - return udm::Type::Srgba; - if(isType.template operator()()) - return udm::Type::HdrColor; - if(isType.template operator()()) - return udm::Type::Transform; - if(isType.template operator()()) - return udm::Type::ScaledTransform; - if(isType.template operator()()) - return udm::Type::Mat4; - if(isType.template operator()()) - return udm::Type::Mat3x4; - if(isType.template operator()()) - return udm::Type::Vector2i; - if(isType.template operator()()) - return udm::Type::Vector3i; - if(isType.template operator()()) - return udm::Type::Vector4i; - return udm::Type::Invalid; -} - template static T &get_lua_object_udm_value(const luabind::object &o) requires(!std::is_arithmetic_v) @@ -424,7 +382,7 @@ static void set_numeric_component(T &value, int32_t idx, lua_udm_underlying_nume static Lua::type get_numeric_component(lua_State *l, const luabind::object &value, int32_t idx, udm::Type type) { - type = (type != udm::Type::Invalid) ? type : determine_lua_object_udm_type(value); + type = (type != udm::Type::Invalid) ? type : Lua::udm::determine_udm_type(value); if(type == udm::Type::Invalid) return Lua::nil; return ::udm::visit_ng(type, [l, &value, idx](auto tag) { @@ -439,7 +397,7 @@ static Lua::type get_numeric_component(lua_State *l, const luabind::ob static luabind::object set_numeric_component(lua_State *l, const luabind::object &value, int32_t idx, udm::Type type, const Lua::udm_numeric &componentValue) { - type = (type != udm::Type::Invalid) ? type : determine_lua_object_udm_type(value); + type = (type != udm::Type::Invalid) ? type : Lua::udm::determine_udm_type(value); if(type == udm::Type::Invalid) return Lua::nil; return ::udm::visit_ng(type, [l, &value, idx, &componentValue](auto tag) { @@ -458,7 +416,7 @@ static luabind::object set_numeric_component(lua_State *l, const luabind::object static Lua::udm_ng lerp_value(lua_State *l, const luabind::object &value0, const luabind::object &value1, float t, udm::Type type) { - type = (type != udm::Type::Invalid) ? type : determine_lua_object_udm_type(value0); + type = (type != udm::Type::Invalid) ? type : Lua::udm::determine_udm_type(value0); if(type == udm::Type::Invalid) return Lua::nil; return ::udm::visit_ng(type, [l, &value0, &value1, t, type](auto tag) { @@ -901,7 +859,7 @@ void Lua::udm::register_library(Lua::Interface &lua) {"ASCII_SAVE_FLAG_BIT_INCLUDE_HEADER", umath::to_integral(::udm::AsciiSaveFlags::IncludeHeader)}, {"ASCII_SAVE_FLAG_BIT_DONT_COMPRESS_LZ4_ARRAYS", umath::to_integral(::udm::AsciiSaveFlags::DontCompressLz4Arrays)}, {"ASCII_SAVE_FLAG_DEFAULT", umath::to_integral(::udm::AsciiSaveFlags::Default)}, - + {"FORMAT_TYPE_BINARY", umath::to_integral(::udm::FormatType::Binary)}, {"FORMAT_TYPE_ASCII", umath::to_integral(::udm::FormatType::Ascii)}, }); From be03e967afda82e63bbd2fa66572ac420176e12f Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 21:30:47 +0100 Subject: [PATCH 19/64] feat(shader_graph): add base scene graph shader and node implementation --- build_scripts/build.py | 2 +- build_scripts/scripts/external_libs.py | 2 +- core/client/include/pragma/c_engine.h | 6 + .../rendering/shader_graph/nodes/camera.hpp | 32 ++++ .../rendering/shader_graph/nodes/fog.hpp | 29 ++++ .../rendering/shader_graph/nodes/lightmap.hpp | 28 ++++ .../rendering/shader_graph/nodes/object.hpp | 27 ++++ .../shader_graph/nodes/scene_output.hpp | 28 ++++ .../shader_graph/nodes/shader_material.hpp | 27 ++++ .../rendering/shader_graph/nodes/time.hpp | 29 ++++ .../pragma/rendering/shader_graph_manager.hpp | 68 ++++++++ .../shaders/world/c_shader_graph.hpp | 37 +++++ core/client/src/c_engine.cpp | 38 ++++- core/client/src/lua/c_luaclass.cpp | 151 ++++++++++++++++- .../rendering/shader_graph/nodes/camera.cpp | 38 +++++ .../src/rendering/shader_graph/nodes/fog.cpp | 31 ++++ .../rendering/shader_graph/nodes/lightmap.cpp | 19 +++ .../rendering/shader_graph/nodes/object.cpp | 27 ++++ .../shader_graph/nodes/scene_output.cpp | 27 ++++ .../shader_graph/nodes/shader_material.cpp | 39 +++++ .../src/rendering/shader_graph/nodes/time.cpp | 31 ++++ .../src/rendering/shader_graph_manager.cpp | 153 ++++++++++++++++++ .../shaders/world/c_shader_graph.cpp | 88 ++++++++++ 23 files changed, 950 insertions(+), 7 deletions(-) create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/fog.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/lightmap.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/object.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/scene_output.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/shader_material.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/time.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph_manager.hpp create mode 100644 core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp create mode 100644 core/client/src/rendering/shader_graph/nodes/camera.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/fog.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/lightmap.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/object.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/scene_output.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/shader_material.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/time.cpp create mode 100644 core/client/src/rendering/shader_graph_manager.cpp create mode 100644 core/client/src/rendering/shaders/world/c_shader_graph.cpp diff --git a/build_scripts/build.py b/build_scripts/build.py index 77dea358b..6fa5764f0 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -1137,7 +1137,7 @@ def download_addon(name,addonName,url,commitId=None): if not skip_repository_updates: if with_pfm: download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","b0cc0afcdb96aab8a5fe778fb20aef7eb5329115") - download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","bd4844c06b9a42bacd17bb7e52d3381c3fd119e4") + download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","a9ea4820f03be250bdf1e6951dad313561b75b17") if with_vr: download_addon("VR","virtual_reality","https://github.com/Silverlan/PragmaVR.git","93fe4f849493651c14133ddf1963b0a8b719f836") diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 5254b4692..4316a54ad 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -32,7 +32,7 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") -get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","33b89dfa095b64414703de5bcf9a7f9cd87bcbf6") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","610d417e369a7a7408ad29949e72f81aab74456e") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") diff --git a/core/client/include/pragma/c_engine.h b/core/client/include/pragma/c_engine.h index 0225b43d1..b31c17cfa 100644 --- a/core/client/include/pragma/c_engine.h +++ b/core/client/include/pragma/c_engine.h @@ -37,6 +37,9 @@ namespace pragma::debug { namespace pragma::string { class Utf8String; }; +namespace pragma::rendering { + class ShaderGraphManager; +}; struct InputBindingLayer; struct CoreInputBindingLayer; struct FontSet; @@ -203,6 +206,8 @@ class DLLCLIENT CEngine : public Engine, public pragma::RenderContext { // Shaders ::util::WeakHandle ReloadShader(const std::string &name); void ReloadShaderPipelines(); + pragma::rendering::ShaderGraphManager &GetShaderGraphManager() { return *m_shaderGraphManager; } + const pragma::rendering::ShaderGraphManager &GetShaderGraphManager() const { return const_cast(this)->GetShaderGraphManager(); } // Double GetDeltaFrameTime() const; @@ -272,6 +277,7 @@ class DLLCLIENT CEngine : public Engine, public pragma::RenderContext { float m_nearZ, m_farZ; std::unique_ptr m_clInstance; std::unique_ptr m_clConfig; + std::unique_ptr m_shaderGraphManager; std::optional m_renderResolution = {}; std::shared_ptr m_gpuProfiler; diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp new file mode 100644 index 000000000..11244ded4 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_CAMERA_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_CAMERA_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT CameraNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_POSITION = "position"; + static constexpr const char *OUT_FOV = "fov"; + static constexpr const char *OUT_NEARZ = "nearZ"; + static constexpr const char *OUT_FARZ = "farZ"; + static constexpr const char *OUT_VIEW_MATRIX = "viewMatrix"; + static constexpr const char *OUT_PROJECTION_MATRIX = "projectionMatrix"; + static constexpr const char *OUT_VIEW_PROJECTION_MATRIX = "viewProjectionMatrix"; + + CameraNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/fog.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/fog.hpp new file mode 100644 index 000000000..084b807ce --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/fog.hpp @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_FOG_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_FOG_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT FogNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_COLOR = "color"; + static constexpr const char *OUT_START_DISTANCE = "startDistance"; + static constexpr const char *OUT_END_DISTANCE = "endDistance"; + static constexpr const char *OUT_DENSITY = "density"; + + FogNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/lightmap.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/lightmap.hpp new file mode 100644 index 000000000..50002118c --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/lightmap.hpp @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_LIGHTMAP_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_LIGHTMAP_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT LightmapNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_LIGHT_MAP = "lightMap"; + static constexpr const char *OUT_LIGHT_MAP_INDIRECT = "lightMapIndirect"; + static constexpr const char *OUT_LIGHT_MAP_DOMINANT = "lightMapDominant"; + + LightmapNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/object.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/object.hpp new file mode 100644 index 000000000..ec493881f --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/object.hpp @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_OBJECT_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_OBJECT_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT ObjectNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_MODEL_MATRIX = "modelMatrix"; + static constexpr const char *OUT_COLOR = "color"; + + ObjectNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/scene_output.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/scene_output.hpp new file mode 100644 index 000000000..5fa9684e4 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/scene_output.hpp @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_SCENE_OUTPUT_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_SCENE_OUTPUT_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT SceneOutputNode : public pragma::shadergraph::Node { + public: + static constexpr const char *IN_COLOR = "color"; + static constexpr const char *IN_ALPHA = "alpha"; + static constexpr const char *IN_BLOOM_COLOR = "bloomColor"; + // TODO: Only allow one of these! + SceneOutputNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/shader_material.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/shader_material.hpp new file mode 100644 index 000000000..6b54f8d5e --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/shader_material.hpp @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_SHADER_MATERIAL_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_SHADER_MATERIAL_HPP__ + +#include "pragma/clientdefinitions.h" +#include "pragma/rendering/shader_material/shader_material.hpp" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT ShaderMaterialNode : public pragma::shadergraph::Node { + public: + ShaderMaterialNode(const std::string_view &type, const pragma::rendering::shader_material::ShaderMaterial &shaderMaterial); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + private: + const pragma::rendering::shader_material::ShaderMaterial &m_shaderMaterial; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/time.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/time.hpp new file mode 100644 index 000000000..5340eee94 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/time.hpp @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_TIME_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_TIME_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT TimeNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_TIME = "time"; + static constexpr const char *OUT_DELTA_TIME = "deltaTime"; + static constexpr const char *OUT_REAL_TIME = "realTime"; + static constexpr const char *OUT_DELTA_REAL_TIME = "deltaRealTime"; + + TimeNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph_manager.hpp b/core/client/include/pragma/rendering/shader_graph_manager.hpp new file mode 100644 index 000000000..0581d4c75 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph_manager.hpp @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2021 Silverlan + */ + +#ifndef __SHADER_GRAPH_MANAGER_HPP__ +#define __SHADER_GRAPH_MANAGER_HPP__ + +#include +#include +#include +#include + +import pragma.shadergraph; + +namespace pragma::rendering { + class DLLCLIENT ShaderGraphData { + public: + ShaderGraphData(const std::string &typeName, const std::string &identifier, const std::shared_ptr &graph) : m_typeName {typeName}, m_identifier {identifier}, m_graph {graph} {} + const std::string &GetIdentifier() const { return m_identifier; } + void GenerateGlsl(); + private: + std::string m_typeName; + std::string m_identifier; + std::shared_ptr m_graph; + }; + + class ShaderGraphManager; + class DLLCLIENT ShaderGraphTypeManager { + public: + ShaderGraphTypeManager(const std::string &typeName, std::shared_ptr nodeRegistry) : m_typeName {typeName}, m_nodeRegistry {nodeRegistry} {} + void ReloadShader(const std::string &identifier); + std::shared_ptr GetGraph(const std::string &identifier) const; + const std::shared_ptr &GetNodeRegistry() const { return m_nodeRegistry; } + private: + friend ShaderGraphManager; + void RegisterGraph(const std::string &identifier, std::shared_ptr graph); + std::shared_ptr RegisterGraph(const std::string &identifier); + std::shared_ptr CreateGraph() const; + std::string m_typeName; + std::unordered_map> m_graphs; + std::shared_ptr m_nodeRegistry; + }; + + class DLLCLIENT ShaderGraphManager { + public: + static constexpr const char *ROOT_GRAPH_PATH = "scripts/shader_data/graphs/"; + static std::string GetShaderFilePath(const std::string &type, const std::string &identifier); + static std::string GetShaderGraphFilePath(const std::string &type, const std::string &identifier); + + ShaderGraphManager() {} + ~ShaderGraphManager() {} + const std::unordered_map> &GetShaderGraphTypeManagers() const { return m_shaderGraphTypeManagers; } + void RegisterGraphTypeManager(const std::string &type, std::shared_ptr nodeRegistry); + std::shared_ptr RegisterGraph(const std::string &type, const std::string &identifier); + std::shared_ptr CreateGraph(const std::string &type) const; + void ReloadShader(const std::string &identifier); + std::shared_ptr GetGraph(const std::string &identifier) const; + std::shared_ptr GetNodeRegistry(const std::string &type) const; + private: + std::unordered_map> m_shaderGraphTypeManagers; + std::unordered_map m_shaderNameToType; + }; +} + +#endif diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp new file mode 100644 index 000000000..46c56f20f --- /dev/null +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __C_SHADER_GRAPH_HPP__ +#define __C_SHADER_GRAPH_HPP__ + +#include "pragma/rendering/shaders/world/c_shader_textured.hpp" + +class Texture; +namespace pragma { + class DLLCLIENT ShaderGraph : public ShaderGameWorldLightingPass { + public: + ShaderGraph(prosper::IPrContext &context, const std::string &identifier, const std::string &fsShader); + + virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, + prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + protected: + using ShaderGameWorldLightingPass::RecordDraw; + void RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const; + virtual void OnPipelinesInitialized() override; + virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override; + virtual void InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) override; + virtual void UpdateRenderFlags(CModelSubMesh &mesh, SceneFlags &inOutFlags) override; + virtual void InitializeGfxPipelineDescriptorSets() override; + std::shared_ptr InitializeMaterialDescriptorSet(CMaterial &mat, const prosper::DescriptorSetInfo &descSetInfo); + + SceneFlags m_extRenderFlags = SceneFlags::None; + std::shared_ptr m_defaultPbrDsg = nullptr; + }; +}; + +#endif diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index a592f9aa2..64f3562ab 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -31,6 +31,7 @@ namespace pragma::string { #include "pragma/rendering/c_sci_gpu_timer_manager.hpp" #include #include "pragma/rendering/shaders/world/c_shader_textured.hpp" +#include "pragma/rendering/shader_graph_manager.hpp" #include #include #include @@ -79,7 +80,7 @@ namespace pragma::string { #endif import util_zip; - +import pragma.shadergraph; extern "C" { void DLLCLIENT RunCEngine(int argc, char *argv[]) { @@ -103,6 +104,14 @@ decltype(CEngine::AXIS_PRESS_THRESHOLD) CEngine::AXIS_PRESS_THRESHOLD = 0.5f; // can be bound individually static const auto SEPARATE_JOYSTICK_AXES = true; +#include "pragma/rendering/shader_graph/nodes/scene_output.hpp" +#include "pragma/rendering/shader_graph/nodes/shader_material.hpp" +#include "pragma/rendering/shader_graph/nodes/camera.hpp" +#include "pragma/rendering/shader_graph/nodes/fog.hpp" +#include "pragma/rendering/shader_graph/nodes/lightmap.hpp" +#include "pragma/rendering/shader_graph/nodes/object.hpp" +#include "pragma/rendering/shader_graph/nodes/time.hpp" + CEngine::CEngine(int argc, char *argv[]) : Engine(argc, argv), pragma::RenderContext(), m_nearZ(pragma::BaseEnvCameraComponent::DEFAULT_NEAR_Z), //10.0f), //0.1f m_farZ(pragma::BaseEnvCameraComponent::DEFAULT_FAR_Z), m_fps(0), m_tFPSTime(0.f), m_tLastFrame(util::Clock::now()), m_tDeltaFrameTime(0), m_audioAPI {"fmod"} @@ -182,6 +191,33 @@ CEngine::CEngine(int argc, char *argv[]) return wrapper; }); } + + { + auto regBase = std::make_shared(); + regBase->RegisterNode("math"); + + auto regScene = std::make_shared(); + regScene->RegisterNode("output"); + regScene->RegisterNode("combine_xyz"); + regScene->RegisterNode("camera"); + regScene->RegisterNode("fog"); + regScene->RegisterNode("lightmap"); + regScene->RegisterNode("object"); + regScene->RegisterNode("time"); + + auto shaderMat = pragma::rendering::shader_material::get_cache().Load("pbr"); + auto node = std::make_shared("test", *shaderMat); + regScene->RegisterNode(node); + + regScene->AddChildRegistry(regBase); + + auto regPp = std::make_shared(); + regPp->AddChildRegistry(regBase); + + m_shaderGraphManager = std::make_unique(); + m_shaderGraphManager->RegisterGraphTypeManager("post_processing", regPp); + m_shaderGraphManager->RegisterGraphTypeManager("object", regScene); + } } void CEngine::Release() diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index ded4ddc30..f6b11da38 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/rendering/shader_graph_manager.hpp" #include "pragma/lua/libraries/ludm.hpp" #include #include @@ -78,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +92,9 @@ import pragma.shadergraph; extern DLLCLIENT CEngine *c_engine; extern DLLCLIENT ClientState *client; extern DLLCLIENT CGame *c_game; + +static spdlog::logger &LOGGER_SG = pragma::register_logger("shadergraph"); + static void reload_textures(CMaterial &mat) { auto &data = mat.GetDataBlock(); @@ -128,6 +133,21 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma static void register_shader_graph(lua_State *l, luabind::module_ &modShader) { auto defGraph = luabind::class_("ShaderGraph"); + defGraph.scope[luabind::def( + "load", +[](const std::string &type, const std::string &name) -> std::pair, std::optional> { + auto filePath = pragma::rendering::ShaderGraphManager::GetShaderGraphFilePath(type, name); + auto reg = c_engine->GetShaderGraphManager().GetNodeRegistry(type); + if(!reg) { + LOGGER_SG.error("Failed to load shader graph of type '{}' with name '{}' - no registry found!", type, name); + return {std::shared_ptr {}, std::optional {}}; + } + auto graph = std::make_shared(reg); + std::string err; + auto result = graph->Load(filePath, err); + if(!result) + return {std::shared_ptr {}, std::optional {err}}; + return {graph, {}}; + })]; defGraph.scope[luabind::def( "load", +[](udm::AssetData &assetData, const std::shared_ptr &nodeReg) -> std::pair, std::optional> { auto graph = std::make_shared(nodeReg); @@ -143,10 +163,27 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) "Save", +[](const pragma::shadergraph::Graph &graph, udm::AssetData &assetData) -> std::pair> { std::string err; if(!graph.Save(assetData, err)) - return {false, std::optional {}}; - return {true, err}; + return {false, err}; + return {true, std::optional {}}; + }); + defGraph.def( + "Save", +[](const pragma::shadergraph::Graph &graph, const std::string &type, const std::string &name) -> std::pair> { + auto filePath = pragma::rendering::ShaderGraphManager::GetShaderGraphFilePath(type, name); + std::string err; + filemanager::create_path(ufile::get_path_from_filename(filePath)); + if(!graph.Save(filePath, err)) + return {false, err}; + return {true, std::optional {}}; + }); + defGraph.def( + "AddNode", +[](pragma::shadergraph::Graph &graph, const std::string &type) -> std::shared_ptr { + auto node = graph.AddNode(type); + if(!node) { + LOGGER_SG.error("Failed to add node of type '{}'!", type); + return nullptr; + } + return node; }); - defGraph.def("AddNode", &pragma::shadergraph::Graph::AddNode); defGraph.def("RemoveNode", &pragma::shadergraph::Graph::RemoveNode); defGraph.def("GetNode", &pragma::shadergraph::Graph::GetNode); defGraph.def( @@ -157,6 +194,8 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) t[idx++] = node.get(); return t; }); + defGraph.def("GenerateGlsl", &pragma::shadergraph::Graph::GenerateGlsl); + defGraph.def("DebugPrint", &pragma::shadergraph::Graph::DebugPrint); auto defNode = luabind::class_("Node"); defNode.def("GetType", &pragma::shadergraph::Node::GetType); @@ -179,12 +218,35 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) modShader[defNode]; auto defSocket = luabind::class_("Socket"); + defSocket.add_static_constant("TYPE_BOOLEAN", umath::to_integral(pragma::shadergraph::SocketType::Boolean)); + defSocket.add_static_constant("TYPE_INT", umath::to_integral(pragma::shadergraph::SocketType::Int)); + defSocket.add_static_constant("TYPE_UINT", umath::to_integral(pragma::shadergraph::SocketType::UInt)); + defSocket.add_static_constant("TYPE_FLOAT", umath::to_integral(pragma::shadergraph::SocketType::Float)); + defSocket.add_static_constant("TYPE_COLOR", umath::to_integral(pragma::shadergraph::SocketType::Color)); + defSocket.add_static_constant("TYPE_VECTOR", umath::to_integral(pragma::shadergraph::SocketType::Vector)); + defSocket.add_static_constant("TYPE_POINT", umath::to_integral(pragma::shadergraph::SocketType::Point)); + defSocket.add_static_constant("TYPE_NORMAL", umath::to_integral(pragma::shadergraph::SocketType::Normal)); + defSocket.add_static_constant("TYPE_POINT2", umath::to_integral(pragma::shadergraph::SocketType::Point2)); + defSocket.add_static_constant("TYPE_STRING", umath::to_integral(pragma::shadergraph::SocketType::String)); + defSocket.add_static_constant("TYPE_TRANSFORM", umath::to_integral(pragma::shadergraph::SocketType::Transform)); + defSocket.add_static_constant("TYPE_ENUM", umath::to_integral(pragma::shadergraph::SocketType::Enum)); + defSocket.add_static_constant("TYPE_INVALID", umath::to_integral(pragma::shadergraph::SocketType::Invalid)); + defSocket.scope[luabind::def("udm_to_socket_type", &pragma::shadergraph::to_socket_type)]; + defSocket.scope[luabind::def("to_udm_type", &pragma::shadergraph::to_udm_type)]; + defSocket.scope[luabind::def("to_glsl_type", &pragma::shadergraph::to_glsl_type)]; + defSocket.def_readonly("name", &pragma::shadergraph::Socket::name); defSocket.def_readonly("type", &pragma::shadergraph::Socket::type); modShader[defSocket]; auto defNodeRegistry = luabind::class_("NodeRegistry"); defNodeRegistry.def("GetNode", &pragma::shadergraph::NodeRegistry::GetNode); + defNodeRegistry.def( + "GetNodeTypes", +[](const pragma::shadergraph::NodeRegistry ®) -> std::vector { + std::vector names; + reg.GetNodeTypes(names); + return names; + }); modShader[defNodeRegistry]; auto defGraphNode = luabind::class_("GraphNode"); @@ -193,8 +255,46 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) defGraphNode.def("SetDisplayName", &pragma::shadergraph::GraphNode::SetDisplayName); defGraphNode.def("GetDisplayName", &pragma::shadergraph::GraphNode::GetDisplayName); defGraphNode.def("ClearInputValue", &pragma::shadergraph::GraphNode::ClearInputValue); + defGraphNode.def( + "SetInputValue", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &inputName, luabind::object value) { + auto type = Lua::udm::determine_udm_type(value); + ::udm::visit(type, [&graphNode, &inputName, &value](auto tag) { + using T = typename decltype(tag)::type; + if constexpr(pragma::shadergraph::is_socket_type()) { + auto val = luabind::object_cast(value); + graphNode.SetInputValue(inputName, val); + } + }); + }); + defGraphNode.def( + "GetInputValue", +[](lua_State *l, const pragma::shadergraph::GraphNode &graphNode, const std::string_view &inputName) -> Lua::udm_type { + auto *input = graphNode.FindInput(inputName); + if(!input) + return Lua::nil; + auto type = pragma::shadergraph::to_udm_type(input->GetSocket().type); + if(type == udm::Type::Invalid) + return Lua::nil; + return ::udm::visit(type, [l, &graphNode, &inputName](auto tag) { + using T = typename decltype(tag)::type; + if constexpr(pragma::shadergraph::is_socket_type()) { + T val; + auto res = graphNode.GetInputValue(inputName, val); + if(!res) + return Lua::nil; + return luabind::object {l, val}; + } + return Lua::nil; + }); + }); defGraphNode.def("CanLink", &pragma::shadergraph::GraphNode::CanLink); - defGraphNode.def("Link", &pragma::shadergraph::GraphNode::Link); + defGraphNode.def( + "Link", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &outputName, pragma::shadergraph::GraphNode &linkTarget, const std::string_view &inputName) -> std::pair> { + std::string err; + auto res = graphNode.Link(outputName, linkTarget, inputName, &err); + if(!res) + LOGGER_SG.debug("Failed to link output '{}' of node '{}' ({}) to input '{}' of node '{}' ({}): {}", outputName, graphNode.GetName(), graphNode->GetType(), inputName, linkTarget.GetName(), linkTarget->GetType(), err); + return {res, err.empty() ? std::optional {} : std::optional {err}}; + }); defGraphNode.def("Disconnect", static_cast(&pragma::shadergraph::GraphNode::Disconnect)); defGraphNode.def("IsOutputLinked", &pragma::shadergraph::GraphNode::IsOutputLinked); defGraphNode.def("FindOutputIndex", &pragma::shadergraph::GraphNode::FindOutputIndex); @@ -241,6 +341,7 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) oGraph["EXTENSION_ASCII"] = pragma::shadergraph::Graph::EXTENSION_ASCII; oGraph["PSG_IDENTIFIER"] = pragma::shadergraph::Graph::PSG_IDENTIFIER; oGraph["PSG_VERSION"] = pragma::shadergraph::Graph::PSG_VERSION; + oGraph["ROOT_PATH"] = pragma::rendering::ShaderGraphManager::ROOT_GRAPH_PATH; } void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) @@ -386,6 +487,48 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) } return 0; }}, + {"register_graph", + [](lua_State *l) { + std::string type = Lua::CheckString(l, 1); + std::string identifier = Lua::CheckString(l, 2); + auto &manager = c_engine->GetShaderGraphManager(); + auto graph = manager.RegisterGraph(type, identifier); + Lua::Push(l, graph); + return 1; + }}, + {"create_graph", + [](lua_State *l) { + std::string type = Lua::CheckString(l, 1); + auto &manager = c_engine->GetShaderGraphManager(); + auto graph = manager.CreateGraph(type); + Lua::Push(l, graph); + return 1; + }}, + {"get_graph", + [](lua_State *l) { + std::string identifier = Lua::CheckString(l, 1); + auto &manager = c_engine->GetShaderGraphManager(); + auto graph = manager.GetGraph(identifier); + Lua::Push(l, graph); + return 1; + }}, + {"reload_graph_shader", + [](lua_State *l) { + std::string identifier = Lua::CheckString(l, 1); + auto &manager = c_engine->GetShaderGraphManager(); + manager.ReloadShader(identifier); + return 0; + }}, + {"get_graph_node_registry", + [](lua_State *l) { + std::string type = Lua::CheckString(l, 1); + auto &manager = c_engine->GetShaderGraphManager(); + auto reg = manager.GetNodeRegistry(type); + if(!reg) + return 0; + Lua::Push(l, reg); + return 1; + }}, {"get", [](lua_State *l) { auto *className = Lua::CheckString(l, 1); diff --git a/core/client/src/rendering/shader_graph/nodes/camera.cpp b/core/client/src/rendering/shader_graph/nodes/camera.cpp new file mode 100644 index 000000000..dd67beafc --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/camera.cpp @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/camera.hpp" + +using namespace pragma::rendering::shader_graph; + +CameraNode::CameraNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_POSITION, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_FOV, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_NEARZ, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_FARZ, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_VIEW_MATRIX, pragma::shadergraph::SocketType::Transform); + AddOutput(OUT_PROJECTION_MATRIX, pragma::shadergraph::SocketType::Transform); + AddOutput(OUT_VIEW_PROJECTION_MATRIX, pragma::shadergraph::SocketType::Transform); + + AddModuleDependency("camera"); + AddModuleDependency("render_settings"); +} + +std::string CameraNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << instance.GetOutputVarName(OUT_POSITION) << " = u_renderSettings.posCam.xyz;\n"; + code << instance.GetOutputVarName(OUT_FOV) << " = u_renderSettings.posCam.w;\n"; + code << instance.GetOutputVarName(OUT_NEARZ) << " = u_renderSettings.nearZ;\n"; + code << instance.GetOutputVarName(OUT_FARZ) << " = u_renderSettings.farZ;\n"; + code << instance.GetOutputVarName(OUT_VIEW_MATRIX) << " = u_camera.V;\n"; + code << instance.GetOutputVarName(OUT_PROJECTION_MATRIX) << " = u_camera.P;\n"; + code << instance.GetOutputVarName(OUT_VIEW_PROJECTION_MATRIX) << " = u_camera.VP;\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/fog.cpp b/core/client/src/rendering/shader_graph/nodes/fog.cpp new file mode 100644 index 000000000..868d0f789 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/fog.cpp @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/fog.hpp" + +using namespace pragma::rendering::shader_graph; + +FogNode::FogNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_COLOR, pragma::shadergraph::SocketType::Color); + AddOutput(OUT_START_DISTANCE, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_END_DISTANCE, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_DENSITY, pragma::shadergraph::SocketType::Float); + + AddModuleDependency("fog"); +} + +std::string FogNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << instance.GetOutputVarName(OUT_COLOR) << " = u_fog.color.rgb;\n"; + code << instance.GetOutputVarName(OUT_START_DISTANCE) << " = u_fog.start;\n"; + code << instance.GetOutputVarName(OUT_END_DISTANCE) << " = u_fog.end;\n"; + code << instance.GetOutputVarName(OUT_DENSITY) << " = u_fog.density;\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/lightmap.cpp b/core/client/src/rendering/shader_graph/nodes/lightmap.cpp new file mode 100644 index 000000000..815b8742b --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/lightmap.cpp @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/lightmap.hpp" + +using namespace pragma::rendering::shader_graph; + +LightmapNode::LightmapNode(const std::string_view &type) : Node {type} { AddModuleDependency("lightmap"); } + +std::string LightmapNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/object.cpp b/core/client/src/rendering/shader_graph/nodes/object.cpp new file mode 100644 index 000000000..dc29994c6 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/object.cpp @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/object.hpp" + +using namespace pragma::rendering::shader_graph; + +ObjectNode::ObjectNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_MODEL_MATRIX, pragma::shadergraph::SocketType::Transform); + AddOutput(OUT_COLOR, pragma::shadergraph::SocketType::Color); + + AddModuleDependency("object"); +} + +std::string ObjectNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << instance.GetOutputVarName(OUT_MODEL_MATRIX) << " = u_instance.M;\n"; + code << instance.GetOutputVarName(OUT_COLOR) << " = u_instance.color;\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/scene_output.cpp b/core/client/src/rendering/shader_graph/nodes/scene_output.cpp new file mode 100644 index 000000000..7f8f0ab1e --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/scene_output.cpp @@ -0,0 +1,27 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2021 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/scene_output.hpp" + +using namespace pragma::rendering::shader_graph; + +SceneOutputNode::SceneOutputNode(const std::string_view &type) : Node {type} +{ + AddInput(IN_COLOR, pragma::shadergraph::SocketType::Color, Vector3 {1.f, 1.f, 1.f}); + AddInput(IN_ALPHA, pragma::shadergraph::SocketType::Float, 1.f); + AddInput(IN_BLOOM_COLOR, pragma::shadergraph::SocketType::Color, Vector3 {0.f, 0.f, 0.f}); +} + +std::string SceneOutputNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << "fs_color = vec4(" << GetInputNameOrValue(instance, IN_COLOR) << ", " << GetInputNameOrValue(instance, IN_ALPHA) << ");\n"; + code << "fs_brightColor = vec4(" << GetInputNameOrValue(instance, IN_BLOOM_COLOR) << ", 1.0);\n"; + return code.str(); + // +} diff --git a/core/client/src/rendering/shader_graph/nodes/shader_material.cpp b/core/client/src/rendering/shader_graph/nodes/shader_material.cpp new file mode 100644 index 000000000..e268aaff4 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/shader_material.cpp @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2021 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/shader_material.hpp" + +using namespace pragma::rendering::shader_graph; + +ShaderMaterialNode::ShaderMaterialNode(const std::string_view &type, const pragma::rendering::shader_material::ShaderMaterial &shaderMaterial) : pragma::shadergraph::Node {type}, m_shaderMaterial {shaderMaterial} +{ + for(auto &prop : m_shaderMaterial.properties) { + auto socketType = pragma::shadergraph::to_socket_type(prop.type); + if(socketType == pragma::shadergraph::SocketType::Invalid) + continue; + AddOutput(prop.name.c_str(), socketType); + } +} +std::string ShaderMaterialNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + // TODO: Only write output var is output is set? + // get_mat_x(); + std::ostringstream code; + for(auto &prop : m_shaderMaterial.properties) { + auto socketType = pragma::shadergraph::to_socket_type(prop.type); + if(socketType == pragma::shadergraph::SocketType::Invalid) + continue; + if(!instance.IsOutputLinked(prop.name)) + continue; + auto *glslType = pragma::shadergraph::to_glsl_type(socketType); + code << glslType << " "; + code << instance.GetOutputVarName(prop.name.c_str()) << " = "; + code << "get_mat_" << prop.name.c_str() << "();\n"; + } + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/time.cpp b/core/client/src/rendering/shader_graph/nodes/time.cpp new file mode 100644 index 000000000..abb08998e --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/time.cpp @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/time.hpp" + +using namespace pragma::rendering::shader_graph; + +TimeNode::TimeNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_TIME, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_DELTA_TIME, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_REAL_TIME, pragma::shadergraph::SocketType::Float); + AddOutput(OUT_DELTA_REAL_TIME, pragma::shadergraph::SocketType::Float); + + AddModuleDependency("time"); +} + +std::string TimeNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << instance.GetOutputVarName(OUT_TIME) << " = u_time.time;\n"; + code << instance.GetOutputVarName(OUT_DELTA_TIME) << " = u_time.deltaTime;\n"; + code << instance.GetOutputVarName(OUT_REAL_TIME) << " = u_time.realTime;\n"; + code << instance.GetOutputVarName(OUT_DELTA_REAL_TIME) << " = u_time.deltaRealTime;\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph_manager.cpp b/core/client/src/rendering/shader_graph_manager.cpp new file mode 100644 index 000000000..298e6876e --- /dev/null +++ b/core/client/src/rendering/shader_graph_manager.cpp @@ -0,0 +1,153 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph_manager.hpp" +#include "pragma/rendering/shaders/world/c_shader_graph.hpp" + +extern DLLCLIENT CEngine *c_engine; + +using namespace pragma::rendering; +void ShaderGraphTypeManager::RegisterGraph(const std::string &identifier, std::shared_ptr graph) +{ + auto fragFilePath = util::FilePath(ShaderGraphManager::GetShaderFilePath(m_typeName, identifier)); + fragFilePath.PopFront(); + auto strFragFilePath = fragFilePath.GetString(); + auto &shaderManager = c_engine->GetShaderManager(); + auto shader = shaderManager.GetShader(identifier); + if(shader.valid()) { + auto *sgShader = dynamic_cast(shader.get()); + if(!sgShader) + throw std::runtime_error {"Shader '" + identifier + "' already exists and is not a ShaderGraph!"}; + } + else + shaderManager.RegisterShader(identifier, [strFragFilePath](prosper::IPrContext &context, const std::string &identifier) { return new pragma::ShaderGraph {context, identifier, strFragFilePath}; }); + auto graphData = std::make_shared(m_typeName, identifier, graph); + m_graphs[identifier] = graphData; +} + +std::shared_ptr ShaderGraphTypeManager::RegisterGraph(const std::string &identifier) +{ + auto graph = CreateGraph(); + RegisterGraph(identifier, graph); + return graph; +} + +std::shared_ptr ShaderGraphTypeManager::CreateGraph() const { return std::make_shared(m_nodeRegistry); } + +void ShaderGraphTypeManager::ReloadShader(const std::string &identifier) +{ + auto graphData = GetGraph(identifier); + if(!graphData) + return; + graphData->GenerateGlsl(); +} + +std::shared_ptr ShaderGraphTypeManager::GetGraph(const std::string &identifier) const +{ + auto it = m_graphs.find(identifier); + if(it != m_graphs.end()) + return it->second; + return nullptr; +} + +std::string ShaderGraphManager::GetShaderFilePath(const std::string &type, const std::string &identifier) +{ + std::string shaderName = identifier; + auto path = util::FilePath("shaders/programs/graph_shaders/", type, shaderName + ".frag"); + return path.GetString(); +} +std::string ShaderGraphManager::GetShaderGraphFilePath(const std::string &type, const std::string &identifier) +{ + auto path = util::FilePath("scripts/shader_data/graphs/", type, identifier); + auto strPath = path.GetString(); + if(!ufile::compare_extension(strPath, {pragma::shadergraph::Graph::EXTENSION_BINARY, pragma::shadergraph::Graph::EXTENSION_ASCII})) + strPath += "." + std::string {pragma::shadergraph::Graph::EXTENSION_ASCII}; + return strPath; +} +void ShaderGraphManager::RegisterGraphTypeManager(const std::string &type, std::shared_ptr nodeRegistry) { m_shaderGraphTypeManagers[type] = std::make_shared(type, nodeRegistry); } +std::shared_ptr ShaderGraphManager::RegisterGraph(const std::string &type, const std::string &identifier) +{ + auto itType = m_shaderNameToType.find(identifier); + if(itType != m_shaderNameToType.end() && itType->second != type) + throw std::runtime_error {"Shader '" + identifier + "' already registered with type '" + itType->second + "'!"}; + auto it = m_shaderGraphTypeManagers.find(type); + if(it == m_shaderGraphTypeManagers.end()) + return nullptr; + auto graph = it->second->RegisterGraph(identifier); + if(!graph) + return nullptr; + m_shaderNameToType[identifier] = type; + return graph; +} +std::shared_ptr ShaderGraphManager::CreateGraph(const std::string &type) const +{ + auto it = m_shaderGraphTypeManagers.find(type); + if(it == m_shaderGraphTypeManagers.end()) + return nullptr; + return it->second->CreateGraph(); +} +void ShaderGraphManager::ReloadShader(const std::string &identifier) +{ + auto itType = m_shaderNameToType.find(identifier); + if(itType == m_shaderNameToType.end()) + return; + auto &type = itType->second; + auto it = m_shaderGraphTypeManagers.find(type); + if(it == m_shaderGraphTypeManagers.end()) + return; + it->second->ReloadShader(identifier); +} +std::shared_ptr ShaderGraphManager::GetGraph(const std::string &identifier) const +{ + auto itType = m_shaderNameToType.find(identifier); + if(itType == m_shaderNameToType.end()) + return nullptr; + auto &type = itType->second; + auto it = m_shaderGraphTypeManagers.find(type); + if(it == m_shaderGraphTypeManagers.end()) + return nullptr; + return it->second->GetGraph(identifier); +} + +std::shared_ptr ShaderGraphManager::GetNodeRegistry(const std::string &type) const +{ + auto it = m_shaderGraphTypeManagers.find(type); + if(it == m_shaderGraphTypeManagers.end()) + return nullptr; + return it->second->GetNodeRegistry(); +} + +void ShaderGraphData::GenerateGlsl() +{ + auto placeholder = filemanager::read_file("shaders/graph_placeholder.frag"); + if(!placeholder) + return; + + std::string shaderName = m_identifier; + std::ostringstream header; + std::ostringstream body; + m_graph->GenerateGlsl(header, body); + + auto strHeader = header.str(); + auto strBody = body.str(); + + ustring::replace(strBody, "\n", "\n\t"); + + auto code = *placeholder; + ustring::replace(code, "{{header}}", strHeader); + ustring::replace(code, "{{body}}", strBody); + + auto path = ShaderGraphManager::GetShaderFilePath(m_typeName, m_identifier); + filemanager::create_path(ufile::get_path_from_filename(path)); + std::string err; + auto f = filemanager::open_file(path, filemanager::FileMode::Write, &err); + if(!f) + return; + f->WriteString(code); + f = {}; +} diff --git a/core/client/src/rendering/shaders/world/c_shader_graph.cpp b/core/client/src/rendering/shaders/world/c_shader_graph.cpp new file mode 100644 index 000000000..236fc88f4 --- /dev/null +++ b/core/client/src/rendering/shaders/world/c_shader_graph.cpp @@ -0,0 +1,88 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shaders/world/c_shader_graph.hpp" +#include "cmaterialmanager.h" +#include "pragma/entities/environment/c_env_reflection_probe.hpp" +#include "pragma/entities/environment/c_env_camera.h" +#include "pragma/rendering/renderers/rasterization_renderer.hpp" +#include "pragma/rendering/render_processor.hpp" +#include "pragma/rendering/shader_material/shader_material.hpp" +#include "pragma/model/vk_mesh.h" +#include "pragma/model/c_modelmesh.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern DLLCLIENT CGame *c_game; +extern DLLCLIENT ClientState *client; +extern DLLCLIENT CEngine *c_engine; + +import pragma.shadergraph; + +using namespace pragma; + +ShaderGraph::ShaderGraph(prosper::IPrContext &context, const std::string &identifier, const std::string &fsShader) : ShaderGameWorldLightingPass {context, identifier, "programs/scene/textured", fsShader} {} + +void ShaderGraph::UpdateRenderFlags(CModelSubMesh &mesh, SceneFlags &inOutFlags) +{ + ShaderGameWorldLightingPass::UpdateRenderFlags(mesh, inOutFlags); + inOutFlags |= m_extRenderFlags; +} +void ShaderGraph::InitializeGfxPipelineDescriptorSets() { ShaderGameWorldLightingPass::InitializeGfxPipelineDescriptorSets(); } + +void ShaderGraph::InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) +{ + ShaderGameWorldLightingPass::InitializeMaterialData(mat, shaderMat, inOutMatData); + auto &data = mat.GetDataBlock(); + float specularFactor; + if(data->GetFloat("specular_factor", &specularFactor)) { + auto roughnessFactor = inOutMatData.GetValue("roughness_factor"); + if(!roughnessFactor) + roughnessFactor = 1.f; + *roughnessFactor *= (1.f - specularFactor); + inOutMatData.SetValue("roughness_factor", *roughnessFactor); + } +} + +std::shared_ptr ShaderGraph::InitializeMaterialDescriptorSet(CMaterial &mat, const prosper::DescriptorSetInfo &descSetInfo) { return ShaderGameWorldLightingPass::InitializeMaterialDescriptorSet(mat, descSetInfo); } +void ShaderGraph::OnPipelinesInitialized() { ShaderGameWorldLightingPass::OnPipelinesInitialized(); } +void ShaderGraph::InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) { ShaderGameWorldLightingPass::InitializeGfxPipeline(pipelineInfo, pipelineIdx); } + +// + +void ShaderGraph::RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const +{ + outIblStrength = 1.f; + std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsLights, &dsShadows}; + + static const std::vector dynamicOffsets {}; + shaderProcessor.GetCommandBuffer().RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, shaderProcessor.GetCurrentPipelineLayout(), GetSceneDescriptorSetIndex(), descSets, dynamicOffsets); +} + +void ShaderGraph::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, + prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const +{ + auto iblStrength = 1.f; + RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows, inOutSceneFlags, iblStrength); + + ShaderGameWorldLightingPass::PushConstants pushConstants {}; + pushConstants.Initialize(); + pushConstants.debugMode = scene.GetDebugMode(); + pushConstants.reflectionProbeIntensity = iblStrength; + pushConstants.flags = inOutSceneFlags; + pushConstants.drawOrigin = drawOrigin; + shaderProcessor.GetCommandBuffer().RecordPushConstants(shaderProcessor.GetCurrentPipelineLayout(), prosper::ShaderStageFlags::VertexBit | prosper::ShaderStageFlags::FragmentBit, 0u, sizeof(pushConstants), &pushConstants); +} From e8dfab9b28ab71356546db1cbd5ee882341a69c4 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 21:31:37 +0100 Subject: [PATCH 20/64] feat(shader_graph): update ui elements --- .../lua/gui/shader_graph/node.lua | 33 +++++++---- .../lua/gui/shader_graph/node_socket.lua | 4 +- .../lua/gui/shader_graph/shader_graph.lua | 58 +++++++++++++++---- .../rendering/shader_graph/nodes/camera.hpp | 14 +++++ .../src/rendering/shader_graph_manager.cpp | 1 + 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/node.lua b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua index 847b8b6b4..bcae8f9be 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/node.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua @@ -18,6 +18,9 @@ function Element:OnInitialize() local box = gui.create("WIVBox", self, 0, 0, self:GetWidth(), self:GetHeight()) box:SetName("global_container") box:SetFixedWidth(true) + box:AddCallback("SetSize", function() + self:SetHeight(box:GetBottom()) + end) local outputControls = gui.create("WIPFMControlsMenu", box, 0, 0, box:GetWidth(), box:GetHeight()) outputControls:SetAutoFillContentsToHeight(false) @@ -28,9 +31,6 @@ function Element:OnInitialize() gui.create("WIPFMControlsMenu", box, 0, outputControls:GetBottom(), box:GetWidth(), box:GetHeight()) inputControls:SetAutoFillContentsToHeight(false) inputControls:SetFixedHeight(false) - inputControls:AddCallback("SetSize", function() - self:SetHeight(inputControls:GetBottom()) - end) self.m_inputControls = inputControls self.m_inputs = {} @@ -47,12 +47,17 @@ end function Element:GetNode() return self.m_node end -function Element:AddControl(socketType, title, id) +function Element:AddControl(socketType, title, id, type) local ctrlMenu = (socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT) and self.m_inputControls or self.m_outputControls - local elCtrl = ctrlMenu:AddSliderControl(title, id, 0.01, 0.0, 0.1, function(el, value) - -- - end, 0.001) + local elCtrl + if socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT and type ~= nil then + local wrapper = ctrlMenu:AddPropertyControl(type, id, title, {}) + elCtrl = wrapper:GetWrapperElement() + else + local el, wrapper = ctrlMenu:AddText(title, id, "") + elCtrl = wrapper + end local el = gui.create("WIGraphNodeSocket", elCtrl) el:SetSocket(self, id, socketType) el:SetMouseInputEnabled(true) @@ -67,7 +72,7 @@ function Element:AddControl(socketType, title, id) socketElement = el, controlElement = elCtrl, } - return el + return el, elCtrl end function Element:GetSocket(socketType, name) local t = (socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT) and self.m_inputs or self.m_outputs @@ -82,12 +87,16 @@ end function Element:GetOutputSocket(name) return self:GetSocket(gui.GraphNodeSocket.SOCKET_TYPE_OUTPUT, name) end -function Element:AddInput(name) - return self:AddControl(gui.GraphNodeSocket.SOCKET_TYPE_INPUT, name, name) +function Element:AddInput(name, type) + local elSocket, elCtrl = self:AddControl(gui.GraphNodeSocket.SOCKET_TYPE_INPUT, name, name, type) + elSocket:SetX(elSocket:GetWidth() * -0.5) + elSocket:SetY(elCtrl:GetHeight() * 0.5 - elSocket:GetHeight() * 0.5) + return elSocket end function Element:AddOutput(name) - local elSocket = self:AddControl(gui.GraphNodeSocket.SOCKET_TYPE_OUTPUT, name, name) - elSocket:SetX(self:GetWidth() - elSocket:GetWidth()) + local elSocket, elCtrl = self:AddControl(gui.GraphNodeSocket.SOCKET_TYPE_OUTPUT, name, name) + elSocket:SetX(elCtrl:GetWidth() - elSocket:GetWidth() * 0.5) + elSocket:SetY(elCtrl:GetHeight() * 0.5 - elSocket:GetHeight() * 0.5) elSocket:SetAnchor(1, 0, 1, 0) return elSocket end diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua b/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua index 20f6eb0b1..f3cf9adda 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/node_socket.lua @@ -14,8 +14,8 @@ function Element:OnInitialize() self:SetSize(16, 16) - local bg = gui.create("WIRect", self, 0, 0, self:GetWidth(), self:GetHeight(), 0, 0, 1, 1) - bg:SetColor(Color.Red) + local bg = gui.create("WITexturedRect", self, 0, 0, self:GetWidth(), self:GetHeight(), 0, 0, 1, 1) + bg:SetMaterial("circle") self.m_bg = bg end function Element:SetSocket(node, socket, socketType) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua index bb0ff88ee..327bdd4eb 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua @@ -17,6 +17,7 @@ function Element:OnInitialize() self.m_nameToElementData = {} self.m_nodeData = {} self.m_linkElements = {} + self:Clear() self:SetSize(1280, 1024) self:SetMouseInputEnabled(true) @@ -80,31 +81,55 @@ function Element:MouseCallback(button, state, mods) pFileDialog:SetRootPath("scripts/shader_data/graphs") pFileDialog:Update() end) - pContext:AddItem("Add Node", function() - local graphNode = self.m_graph:AddNode("math") - if graphNode ~= nil then - self:AddNode(graphNode) - self:InitializeLinks() - end + pContext:AddItem("Generate GLSL", function() + util.set_clipboard_string(self.m_graph:GenerateGlsl()) end) + local reg = shader.get_graph_node_registry("object") + if reg ~= nil then + local nodeTypes = reg:GetNodeTypes() + table.sort(nodeTypes) + local pItem, pSubMenu = pContext:AddSubMenu("Add Node") + for _, name in pairs(nodeTypes) do + pSubMenu:AddItem(name, function(pItem) + local graphNode = self.m_graph:AddNode(name) + if graphNode ~= nil then + local frame = self:AddNode(graphNode) + local pos = self:GetCursorPos() + frame:SetPos(pos.x - frame:GetWidth() * 0.5, pos.y - frame:GetHeight() * 0.5) + self:InitializeLinks() + end + end) + end + pSubMenu:Update() + end pContext:Update() return util.EVENT_REPLY_HANDLED end end end -function Element:SetGraph(graph) +function Element:GetGraph() + return self.m_graph +end +function Element:Clear() self:ClearLinks() for _, t in ipairs(self.m_nodeData) do util.remove(t.frame) end self.m_nodeData = {} self.m_nameToElementData = {} + self.m_graph = shader.create_graph("object") +end +function Element:SetGraph(graph) + self:Clear() self.m_graph = graph local nodes = self.m_graph:GetNodes() + local offset = 0 for _, graphNode in ipairs(nodes) do - self:AddNode(graphNode) + local frame = self:AddNode(graphNode) + frame:SetX(offset) + offset = offset + frame:GetWidth() + 80 end self:InitializeLinks() @@ -146,6 +171,7 @@ function Element:AddLink(elOutputSocket, elInputSocket) local l = gui.create("WIElementConnectorLine", self) l:SetSize(self:GetSize()) l:SetAnchor(0, 0, 1, 1) + l:SetZPos(-1) l:Setup(elOutputSocket, elInputSocket) table.insert(self.m_linkElements, l) end @@ -172,7 +198,15 @@ function Element:AddNode(graphNode) frame:SetTitle(name) frame:SetDetachButtonEnabled(false) frame:SetCloseButtonEnabled(false) + frame:SetResizable(false) frame:SetSize(128, 128) + frame:SetZPos(0) + frame:AddCallback("OnDragStart", function(el, x, y) + el:SetZPos(1) + end) + frame:AddCallback("OnDragEnd", function(el, x, y) + el:SetZPos(0) + end) frame:SetMouseInputEnabled(true) frame:AddCallback("OnMouseEvent", function(el, button, state, mods) @@ -201,16 +235,17 @@ function Element:AddNode(graphNode) local elNode = gui.create("WIGraphNode", frame) elNode:SetNode(graphNode:GetName()) elNode:SetY(31) - frame:SetX(#self.m_nodeData * 200) + elNode:AddCallback("SetSize", function() + frame:SetHeight(elNode:GetBottom()) + end) for _, output in ipairs(graphNode:GetOutputs()) do local socket = output:GetSocket() local elOutput = elNode:AddOutput(socket.name) end for _, input in ipairs(graphNode:GetInputs()) do local socket = input:GetSocket() - local elInput = elNode:AddInput(socket.name) + local elInput = elNode:AddInput(socket.name, shader.Socket.to_udm_type(socket.type)) end - --x = elNode:GetRight() + 80 elNode:AddCallback("OnSocketClicked", function(elNode, elSocket, socketType, id) if util.is_valid(self.m_outSocket) == false then @@ -243,5 +278,6 @@ function Element:AddNode(graphNode) } table.insert(self.m_nodeData, t) self.m_nameToElementData[graphNode:GetName()] = t + return frame end gui.register("WIShaderGraph", Element) diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp index 11244ded4..b6c1dd2df 100644 --- a/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp +++ b/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp @@ -29,4 +29,18 @@ namespace pragma::rendering::shader_graph { }; }; +#if 0 +layout(std140, LAYOUT_ID(SCENE, RENDER_SETTINGS)) uniform RenderSettings +{ + vec4 posCam; // w component is fov + int flags; + float shadowRatioX; + float shadowRatioY; + float nearZ; + float farZ; + int shaderQuality; // 1 = lowest, 10 = highest +} +u_renderSettings; +#endif + #endif diff --git a/core/client/src/rendering/shader_graph_manager.cpp b/core/client/src/rendering/shader_graph_manager.cpp index 298e6876e..429aae7bc 100644 --- a/core/client/src/rendering/shader_graph_manager.cpp +++ b/core/client/src/rendering/shader_graph_manager.cpp @@ -12,6 +12,7 @@ extern DLLCLIENT CEngine *c_engine; using namespace pragma::rendering; +#pragma optimize("", off) void ShaderGraphTypeManager::RegisterGraph(const std::string &identifier, std::shared_ptr graph) { auto fragFilePath = util::FilePath(ShaderGraphManager::GetShaderFilePath(m_typeName, identifier)); From 28a96693246c114576f4b2227ddbc667e8ce840c Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 23 Nov 2024 21:33:16 +0100 Subject: [PATCH 21/64] build: update submodule "filmmaker" --- build_scripts/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index 6fa5764f0..80e5d33f0 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -1136,7 +1136,7 @@ def download_addon(name,addonName,url,commitId=None): curDir = os.getcwd() if not skip_repository_updates: if with_pfm: - download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","b0cc0afcdb96aab8a5fe778fb20aef7eb5329115") + download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","7492a21fc643fa831dc45bfcb401bd7b4ecdc2f1") download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","a9ea4820f03be250bdf1e6951dad313561b75b17") if with_vr: From 4201e59f4d49c8450616ee7cd1fde4a42f79c03a Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 25 Nov 2024 09:45:35 +0100 Subject: [PATCH 22/64] feat(debug): add profiling utility functions --- .../include/pragma/debug/debug_utils.hpp | 2 ++ core/shared/src/debug/debug_utils.cpp | 34 +++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/core/shared/include/pragma/debug/debug_utils.hpp b/core/shared/include/pragma/debug/debug_utils.hpp index bb5754af8..5280650f8 100644 --- a/core/shared/include/pragma/debug/debug_utils.hpp +++ b/core/shared/include/pragma/debug/debug_utils.hpp @@ -38,6 +38,8 @@ namespace pragma::debug { #ifdef _WIN32 DLLNETWORK bool is_module_in_callstack(struct _EXCEPTION_POINTERS *exp, const std::string &moduleName); #endif + DLLNETWORK void start_profiling_task(const char *taskName); + DLLNETWORK void end_profiling_task(); }; #endif diff --git a/core/shared/src/debug/debug_utils.cpp b/core/shared/src/debug/debug_utils.cpp index a56219e18..af062066c 100644 --- a/core/shared/src/debug/debug_utils.cpp +++ b/core/shared/src/debug/debug_utils.cpp @@ -7,6 +7,7 @@ #include "stdafx_shared.h" #include "pragma/debug/debug_utils.hpp" +#include #include #include // #include @@ -15,6 +16,19 @@ #include "pragma/localization.h" #endif +void pragma::debug::start_profiling_task(const char *taskName) +{ +#ifdef PRAGMA_ENABLE_VTUNE_PROFILING + ::debug::get_domain().BeginTask(taskName); +#endif +} +void pragma::debug::end_profiling_task() +{ +#ifdef PRAGMA_ENABLE_VTUNE_PROFILING + ::debug::get_domain().EndTask(); +#endif +} + void pragma::debug::open_file_in_zerobrane(const std::string &fileName, uint32_t lineIdx) { std::string zeroBranePath = "C:/Program Files (x86)/ZeroBraneStudio/zbstudio.exe"; // TODO: Find program path from registry? @@ -148,24 +162,24 @@ std::optional pragma::debug::show_message_promp if(buttons.empty()) return {}; std::stringstream cmd; - cmd<<"zenity "; + cmd << "zenity "; if(buttons.size() == 1) - cmd<<"--info "; + cmd << "--info "; else - cmd<<"--question "; - cmd<<"--title='" +*title +"' "; - cmd<<"--text='" +msg +"' "; + cmd << "--question "; + cmd << "--title='" + *title + "' "; + cmd << "--text='" + msg + "' "; auto getButtonText = [](MessageBoxButton button) -> std::string { - auto identifier = ustring::to_snake_case(std::string{magic_enum::enum_name(button)}); - auto text = Locale::GetText("prompt_button_" +identifier); + auto identifier = ustring::to_snake_case(std::string {magic_enum::enum_name(button)}); + auto text = Locale::GetText("prompt_button_" + identifier); return text; }; - cmd<<"--ok-label='"< 1) { - cmd<<"--cancel-label='"< 2) { - cmd<<"--extra-button='"< Date: Mon, 25 Nov 2024 09:47:28 +0100 Subject: [PATCH 23/64] feat(shader_graph): add color input field --- .../lua/gui/shader_graph/node.lua | 23 ++++++++++++++++--- .../lua/gui/shader_graph/shader_graph.lua | 8 ++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/node.lua b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua index bcae8f9be..76efc0c7f 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/node.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua @@ -27,8 +27,15 @@ function Element:OnInitialize() outputControls:SetFixedHeight(false) self.m_outputControls = outputControls - local inputControls = - gui.create("WIPFMControlsMenu", box, 0, outputControls:GetBottom(), box:GetWidth(), box:GetHeight()) + local offsetControls = 0 + local inputControls = gui.create( + "WIPFMControlsMenu", + box, + offsetControls, + outputControls:GetBottom(), + box:GetWidth() - offsetControls, + box:GetHeight() + ) inputControls:SetAutoFillContentsToHeight(false) inputControls:SetFixedHeight(false) self.m_inputControls = inputControls @@ -52,7 +59,17 @@ function Element:AddControl(socketType, title, id, type) or self.m_outputControls local elCtrl if socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT and type ~= nil then - local wrapper = ctrlMenu:AddPropertyControl(type, id, title, {}) + local udmType = shader.Socket.to_udm_type(type) + local propInfo = {} + if type == shader.Socket.TYPE_COLOR then + propInfo.specializationType = "color" + end + local wrapper = ctrlMenu:AddPropertyControl(udmType, id, title, propInfo) + wrapper:SetOnChangeValueHandler(function(val, isFinal, initialValue) + if isFinal then + self:CallCallbacks("OnSocketValueChanged", id, val) + end + end) elCtrl = wrapper:GetWrapperElement() else local el, wrapper = ctrlMenu:AddText(title, id, "") diff --git a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua index 327bdd4eb..d4539169f 100644 --- a/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua +++ b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua @@ -238,13 +238,19 @@ function Element:AddNode(graphNode) elNode:AddCallback("SetSize", function() frame:SetHeight(elNode:GetBottom()) end) + elNode:AddCallback("OnSocketValueChanged", function(elNode, id, val) + local node = self.m_graph:GetNode(name) + if node:SetInputValue(id, val) then + self:CallCallbacks("OnNodeSocketValueChanged", name, id, val) + end + end) for _, output in ipairs(graphNode:GetOutputs()) do local socket = output:GetSocket() local elOutput = elNode:AddOutput(socket.name) end for _, input in ipairs(graphNode:GetInputs()) do local socket = input:GetSocket() - local elInput = elNode:AddInput(socket.name, shader.Socket.to_udm_type(socket.type)) + local elInput = elNode:AddInput(socket.name, socket.type) end elNode:AddCallback("OnSocketClicked", function(elNode, elSocket, socketType, id) From 7f43e2bf18796c1e7486efdde10e6854a6d02485 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 25 Nov 2024 09:52:13 +0100 Subject: [PATCH 24/64] feat(shader_graph): add module system --- assets/shaders/modules/pbr.glsl | 1 + .../manager.hpp} | 12 ++- .../pragma/rendering/shader_graph/module.hpp | 49 ++++++++++ .../rendering/shader_graph/modules/pbr.hpp | 40 +++++++++ .../rendering/shader_graph/nodes/pbr.hpp | 31 +++++++ .../shaders/world/c_shader_graph.hpp | 10 ++- core/client/src/c_engine.cpp | 7 +- core/client/src/lua/c_luaclass.cpp | 89 +++++++++---------- .../manager.cpp} | 36 +++++++- .../src/rendering/shader_graph/module.cpp | 21 +++++ .../rendering/shader_graph/modules/pbr.cpp | 67 ++++++++++++++ .../src/rendering/shader_graph/nodes/pbr.cpp | 56 ++++++++++++ .../shaders/world/c_shader_graph.cpp | 66 ++++++++++---- 13 files changed, 411 insertions(+), 74 deletions(-) create mode 100644 assets/shaders/modules/pbr.glsl rename core/client/include/pragma/rendering/{shader_graph_manager.hpp => shader_graph/manager.hpp} (86%) create mode 100644 core/client/include/pragma/rendering/shader_graph/module.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/modules/pbr.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/pbr.hpp rename core/client/src/rendering/{shader_graph_manager.cpp => shader_graph/manager.cpp} (80%) create mode 100644 core/client/src/rendering/shader_graph/module.cpp create mode 100644 core/client/src/rendering/shader_graph/modules/pbr.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/pbr.cpp diff --git a/assets/shaders/modules/pbr.glsl b/assets/shaders/modules/pbr.glsl new file mode 100644 index 000000000..168c2b389 --- /dev/null +++ b/assets/shaders/modules/pbr.glsl @@ -0,0 +1 @@ +#include "/common/pbr/fs_pbr.glsl" diff --git a/core/client/include/pragma/rendering/shader_graph_manager.hpp b/core/client/include/pragma/rendering/shader_graph/manager.hpp similarity index 86% rename from core/client/include/pragma/rendering/shader_graph_manager.hpp rename to core/client/include/pragma/rendering/shader_graph/manager.hpp index 0581d4c75..f846dcfb2 100644 --- a/core/client/include/pragma/rendering/shader_graph_manager.hpp +++ b/core/client/include/pragma/rendering/shader_graph/manager.hpp @@ -20,6 +20,8 @@ namespace pragma::rendering { public: ShaderGraphData(const std::string &typeName, const std::string &identifier, const std::shared_ptr &graph) : m_typeName {typeName}, m_identifier {identifier}, m_graph {graph} {} const std::string &GetIdentifier() const { return m_identifier; } + const std::string &GetTypeName() const { return m_typeName; } + const std::shared_ptr &GetGraph() const { return m_graph; } void GenerateGlsl(); private: std::string m_typeName; @@ -44,24 +46,30 @@ namespace pragma::rendering { std::shared_ptr m_nodeRegistry; }; + class ShaderGraphModuleManager; class DLLCLIENT ShaderGraphManager { public: static constexpr const char *ROOT_GRAPH_PATH = "scripts/shader_data/graphs/"; static std::string GetShaderFilePath(const std::string &type, const std::string &identifier); static std::string GetShaderGraphFilePath(const std::string &type, const std::string &identifier); - ShaderGraphManager() {} - ~ShaderGraphManager() {} + ShaderGraphManager(); + ~ShaderGraphManager(); const std::unordered_map> &GetShaderGraphTypeManagers() const { return m_shaderGraphTypeManagers; } void RegisterGraphTypeManager(const std::string &type, std::shared_ptr nodeRegistry); std::shared_ptr RegisterGraph(const std::string &type, const std::string &identifier); std::shared_ptr CreateGraph(const std::string &type) const; + std::shared_ptr LoadShader(const std::string &identifier, std::string &outErr); void ReloadShader(const std::string &identifier); std::shared_ptr GetGraph(const std::string &identifier) const; std::shared_ptr GetNodeRegistry(const std::string &type) const; + + ShaderGraphModuleManager &GetModuleManager(); + const ShaderGraphModuleManager &GetModuleManager() const; private: std::unordered_map> m_shaderGraphTypeManagers; std::unordered_map m_shaderNameToType; + std::unique_ptr m_moduleManager; }; } diff --git a/core/client/include/pragma/rendering/shader_graph/module.hpp b/core/client/include/pragma/rendering/shader_graph/module.hpp new file mode 100644 index 000000000..1c5b5e059 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/module.hpp @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2021 Silverlan + */ + +#ifndef __SHADER_GRAPH_MODULE_HPP__ +#define __SHADER_GRAPH_MODULE_HPP__ + +#include +#include "pragma/rendering/shaders/world/c_shader_scene.hpp" + +namespace prosper { + class Shader; +} + +namespace pragma { + class CSceneComponent; + class CRasterizationRendererComponent; +}; + +class CModelSubMesh; +namespace pragma::rendering { + class ShaderProcessor; + class DLLCLIENT ShaderGraphModule { + public: + ShaderGraphModule(prosper::Shader &shader) : m_shader(shader) {} + virtual ~ShaderGraphModule() {} + virtual void InitializeGfxPipelineDescriptorSets() = 0; + virtual void UpdateRenderFlags(CModelSubMesh &mesh, ShaderGameWorld::SceneFlags &inOutFlags) {} + virtual void RecordBindScene(ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const = 0; + protected: + prosper::Shader &m_shader; + }; + + class DLLCLIENT ShaderGraphModuleManager { + public: + using Factory = std::function(prosper::Shader &shader)>; + ShaderGraphModuleManager() {} + void RegisterFactory(const std::string &name, const Factory &factory); + std::unique_ptr CreateModule(const std::string &name, prosper::Shader &shader) const; + const std::unordered_map &GetFactories() const { return m_factories; } + private: + std::unordered_map m_factories; + }; +} + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/modules/pbr.hpp b/core/client/include/pragma/rendering/shader_graph/modules/pbr.hpp new file mode 100644 index 000000000..56b5694a5 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/modules/pbr.hpp @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_MODULES_PBR_HPP__ +#define __PRAGMA_SHADER_GRAPH_MODULES_PBR_HPP__ + +#include "pragma/clientdefinitions.h" +#include "pragma/rendering/shader_graph/module.hpp" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT PbrModule : public pragma::rendering::ShaderGraphModule { + public: + public: + enum class PBRBinding : uint32_t { + IrradianceMap = 0u, + PrefilterMap, + BRDFMap, + + Count + }; + PbrModule(prosper::Shader &shader); + virtual ~PbrModule() override; + virtual void InitializeGfxPipelineDescriptorSets() override; + virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet *GetReflectionProbeDescriptorSet(const pragma::CSceneComponent &scene, float &outIblStrength, ShaderGameWorld::SceneFlags &inOutSceneFlags) const; + prosper::IDescriptorSet &GetDefaultPbrDescriptorSet() const; + private: + prosper::DescriptorSetInfo m_pbrDescSetInfo; + static std::shared_ptr g_defaultPbrDsg; + static size_t g_instanceCount; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/pbr.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/pbr.hpp new file mode 100644 index 000000000..56d04375a --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/pbr.hpp @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_PBR_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_PBR_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT PbrNode : public pragma::shadergraph::Node { + public: + static constexpr const char *IN_ALBEDO_COLOR = "albedoColor"; + static constexpr const char *IN_METALNESS = "metalness"; + static constexpr const char *IN_ROUGHNESS = "roughness"; + static constexpr const char *IN_AMBIENT_OCCLUSION = "ambientOcclusion"; + + static constexpr const char *OUT_COLOR = "color"; + + PbrNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp index 46c56f20f..f175d0940 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp @@ -12,25 +12,29 @@ class Texture; namespace pragma { + namespace rendering { + class ShaderGraphModule; + }; class DLLCLIENT ShaderGraph : public ShaderGameWorldLightingPass { public: ShaderGraph(prosper::IPrContext &context, const std::string &identifier, const std::string &fsShader); + virtual ~ShaderGraph() override; virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; protected: using ShaderGameWorldLightingPass::RecordDraw; - void RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const; virtual void OnPipelinesInitialized() override; + virtual void ClearShaderResources() override; + virtual void InitializeShaderResources() override; virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override; virtual void InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) override; virtual void UpdateRenderFlags(CModelSubMesh &mesh, SceneFlags &inOutFlags) override; virtual void InitializeGfxPipelineDescriptorSets() override; std::shared_ptr InitializeMaterialDescriptorSet(CMaterial &mat, const prosper::DescriptorSetInfo &descSetInfo); - SceneFlags m_extRenderFlags = SceneFlags::None; std::shared_ptr m_defaultPbrDsg = nullptr; + std::vector> m_modules; }; }; diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 64f3562ab..90b05f34b 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -31,7 +31,7 @@ namespace pragma::string { #include "pragma/rendering/c_sci_gpu_timer_manager.hpp" #include #include "pragma/rendering/shaders/world/c_shader_textured.hpp" -#include "pragma/rendering/shader_graph_manager.hpp" +#include "pragma/rendering/shader_graph/manager.hpp" #include #include #include @@ -111,6 +111,8 @@ static const auto SEPARATE_JOYSTICK_AXES = true; #include "pragma/rendering/shader_graph/nodes/lightmap.hpp" #include "pragma/rendering/shader_graph/nodes/object.hpp" #include "pragma/rendering/shader_graph/nodes/time.hpp" +#include "pragma/rendering/shader_graph/nodes/pbr.hpp" +#include "pragma/rendering/shader_graph/modules/pbr.hpp" CEngine::CEngine(int argc, char *argv[]) : Engine(argc, argv), pragma::RenderContext(), m_nearZ(pragma::BaseEnvCameraComponent::DEFAULT_NEAR_Z), //10.0f), //0.1f @@ -204,6 +206,7 @@ CEngine::CEngine(int argc, char *argv[]) regScene->RegisterNode("lightmap"); regScene->RegisterNode("object"); regScene->RegisterNode("time"); + regScene->RegisterNode("pbr"); auto shaderMat = pragma::rendering::shader_material::get_cache().Load("pbr"); auto node = std::make_shared("test", *shaderMat); @@ -217,6 +220,8 @@ CEngine::CEngine(int argc, char *argv[]) m_shaderGraphManager = std::make_unique(); m_shaderGraphManager->RegisterGraphTypeManager("post_processing", regPp); m_shaderGraphManager->RegisterGraphTypeManager("object", regScene); + + m_shaderGraphManager->GetModuleManager().RegisterFactory("pbr", [](prosper::Shader &shader) -> std::unique_ptr { return std::make_unique(shader); }); } } diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index f6b11da38..3cdd06a6a 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -57,7 +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/rendering/shader_graph_manager.hpp" +#include "pragma/rendering/shader_graph/manager.hpp" #include "pragma/lua/libraries/ludm.hpp" #include #include @@ -256,14 +256,15 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) defGraphNode.def("GetDisplayName", &pragma::shadergraph::GraphNode::GetDisplayName); defGraphNode.def("ClearInputValue", &pragma::shadergraph::GraphNode::ClearInputValue); defGraphNode.def( - "SetInputValue", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &inputName, luabind::object value) { + "SetInputValue", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &inputName, luabind::object value) -> bool { auto type = Lua::udm::determine_udm_type(value); - ::udm::visit(type, [&graphNode, &inputName, &value](auto tag) { + return ::udm::visit(type, [&graphNode, &inputName, &value](auto tag) { using T = typename decltype(tag)::type; if constexpr(pragma::shadergraph::is_socket_type()) { auto val = luabind::object_cast(value); - graphNode.SetInputValue(inputName, val); + return graphNode.SetInputValue(inputName, val); } + return false; }); }); defGraphNode.def( @@ -487,48 +488,6 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) } return 0; }}, - {"register_graph", - [](lua_State *l) { - std::string type = Lua::CheckString(l, 1); - std::string identifier = Lua::CheckString(l, 2); - auto &manager = c_engine->GetShaderGraphManager(); - auto graph = manager.RegisterGraph(type, identifier); - Lua::Push(l, graph); - return 1; - }}, - {"create_graph", - [](lua_State *l) { - std::string type = Lua::CheckString(l, 1); - auto &manager = c_engine->GetShaderGraphManager(); - auto graph = manager.CreateGraph(type); - Lua::Push(l, graph); - return 1; - }}, - {"get_graph", - [](lua_State *l) { - std::string identifier = Lua::CheckString(l, 1); - auto &manager = c_engine->GetShaderGraphManager(); - auto graph = manager.GetGraph(identifier); - Lua::Push(l, graph); - return 1; - }}, - {"reload_graph_shader", - [](lua_State *l) { - std::string identifier = Lua::CheckString(l, 1); - auto &manager = c_engine->GetShaderGraphManager(); - manager.ReloadShader(identifier); - return 0; - }}, - {"get_graph_node_registry", - [](lua_State *l) { - std::string type = Lua::CheckString(l, 1); - auto &manager = c_engine->GetShaderGraphManager(); - auto reg = manager.GetNodeRegistry(type); - if(!reg) - return 0; - Lua::Push(l, reg); - return 1; - }}, {"get", [](lua_State *l) { auto *className = Lua::CheckString(l, 1); @@ -572,6 +531,44 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) return 1; }}}); + modShader[luabind::def( + "register_graph", +[](const std::string &type, const std::string &identifier) -> std::shared_ptr { + auto &manager = c_engine->GetShaderGraphManager(); + return manager.RegisterGraph(type, identifier); + })]; + modShader[luabind::def( + "create_graph", +[](const std::string &type) -> std::shared_ptr { + auto &manager = c_engine->GetShaderGraphManager(); + return manager.CreateGraph(type); + })]; + modShader[luabind::def( + "get_graph", +[](const std::string &identifier) -> std::shared_ptr { + auto &manager = c_engine->GetShaderGraphManager(); + auto graphData = manager.GetGraph(identifier); + if(!graphData) + return nullptr; + return graphData->GetGraph(); + })]; + modShader[luabind::def( + "reload_graph_shader", +[](const std::string &identifier) { + auto &manager = c_engine->GetShaderGraphManager(); + manager.ReloadShader(identifier); + })]; + modShader[luabind::def( + "get_graph_node_registry", +[](const std::string &type) -> std::shared_ptr { + auto &manager = c_engine->GetShaderGraphManager(); + return manager.GetNodeRegistry(type); + })]; + modShader[luabind::def( + "load_shader_graph", +[](const std::string &identifier) -> std::pair, std::optional> { + auto &manager = c_engine->GetShaderGraphManager(); + std::string err; + auto graph = manager.LoadShader(identifier, err); + if(!graph) + return {nullptr, std::optional {err}}; + return {graph, std::optional {}}; + })]; + // These have to match shaders/modules/fs_tonemapping.gls! enum class ToneMapping : uint8_t { None = 0, diff --git a/core/client/src/rendering/shader_graph_manager.cpp b/core/client/src/rendering/shader_graph/manager.cpp similarity index 80% rename from core/client/src/rendering/shader_graph_manager.cpp rename to core/client/src/rendering/shader_graph/manager.cpp index 429aae7bc..c0ad17cd3 100644 --- a/core/client/src/rendering/shader_graph_manager.cpp +++ b/core/client/src/rendering/shader_graph/manager.cpp @@ -6,13 +6,13 @@ */ #include "stdafx_client.h" -#include "pragma/rendering/shader_graph_manager.hpp" +#include "pragma/rendering/shader_graph/manager.hpp" +#include "pragma/rendering/shader_graph/module.hpp" #include "pragma/rendering/shaders/world/c_shader_graph.hpp" extern DLLCLIENT CEngine *c_engine; using namespace pragma::rendering; -#pragma optimize("", off) void ShaderGraphTypeManager::RegisterGraph(const std::string &identifier, std::shared_ptr graph) { auto fragFilePath = util::FilePath(ShaderGraphManager::GetShaderFilePath(m_typeName, identifier)); @@ -20,14 +20,18 @@ void ShaderGraphTypeManager::RegisterGraph(const std::string &identifier, std::s auto strFragFilePath = fragFilePath.GetString(); auto &shaderManager = c_engine->GetShaderManager(); auto shader = shaderManager.GetShader(identifier); + auto graphData = std::make_shared(m_typeName, identifier, graph); if(shader.valid()) { auto *sgShader = dynamic_cast(shader.get()); if(!sgShader) throw std::runtime_error {"Shader '" + identifier + "' already exists and is not a ShaderGraph!"}; } - else + else { + auto path = ShaderGraphManager::GetShaderFilePath(m_typeName, identifier); + if(!filemanager::exists(path)) + graphData->GenerateGlsl(); shaderManager.RegisterShader(identifier, [strFragFilePath](prosper::IPrContext &context, const std::string &identifier) { return new pragma::ShaderGraph {context, identifier, strFragFilePath}; }); - auto graphData = std::make_shared(m_typeName, identifier, graph); + } m_graphs[identifier] = graphData; } @@ -70,6 +74,10 @@ std::string ShaderGraphManager::GetShaderGraphFilePath(const std::string &type, strPath += "." + std::string {pragma::shadergraph::Graph::EXTENSION_ASCII}; return strPath; } +ShaderGraphManager::ShaderGraphManager() : m_moduleManager {std::make_unique()} {} +ShaderGraphManager::~ShaderGraphManager() {} +ShaderGraphModuleManager &ShaderGraphManager::GetModuleManager() { return *m_moduleManager; } +const ShaderGraphModuleManager &ShaderGraphManager::GetModuleManager() const { return *m_moduleManager; } void ShaderGraphManager::RegisterGraphTypeManager(const std::string &type, std::shared_ptr nodeRegistry) { m_shaderGraphTypeManagers[type] = std::make_shared(type, nodeRegistry); } std::shared_ptr ShaderGraphManager::RegisterGraph(const std::string &type, const std::string &identifier) { @@ -92,6 +100,26 @@ std::shared_ptr ShaderGraphManager::CreateGraph(cons return nullptr; return it->second->CreateGraph(); } +std::shared_ptr ShaderGraphManager::LoadShader(const std::string &identifier, std::string &outErr) +{ + auto graph = GetGraph(identifier); + if(graph) + return graph->GetGraph(); + for(auto &[typeName, typeManager] : m_shaderGraphTypeManagers) { + auto path = GetShaderGraphFilePath(typeName, identifier); + if(!filemanager::exists(path)) + continue; + auto graph = std::make_shared(typeManager->GetNodeRegistry()); + auto result = graph->Load(path, outErr); + if(!result) + return nullptr; + typeManager->RegisterGraph(identifier, graph); + m_shaderNameToType[identifier] = typeName; + return graph; + } + outErr = "Failed to load shader graph '" + identifier + "': No shader graph file found!"; + return nullptr; +} void ShaderGraphManager::ReloadShader(const std::string &identifier) { auto itType = m_shaderNameToType.find(identifier); diff --git a/core/client/src/rendering/shader_graph/module.cpp b/core/client/src/rendering/shader_graph/module.cpp new file mode 100644 index 000000000..3d6c36e47 --- /dev/null +++ b/core/client/src/rendering/shader_graph/module.cpp @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/module.hpp" + +using namespace pragma::rendering; + +void ShaderGraphModuleManager::RegisterFactory(const std::string &name, const Factory &factory) { m_factories[name] = factory; } +std::unique_ptr ShaderGraphModuleManager::CreateModule(const std::string &name, prosper::Shader &shader) const +{ + auto it = m_factories.find(name); + if(it == m_factories.end()) + return nullptr; + auto &factory = it->second; + return factory(shader); +} diff --git a/core/client/src/rendering/shader_graph/modules/pbr.cpp b/core/client/src/rendering/shader_graph/modules/pbr.cpp new file mode 100644 index 000000000..07e5db830 --- /dev/null +++ b/core/client/src/rendering/shader_graph/modules/pbr.cpp @@ -0,0 +1,67 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/modules/pbr.hpp" +#include "pragma/rendering/render_processor.hpp" +#include "pragma/entities/environment/c_env_reflection_probe.hpp" +#include "pragma/entities/environment/c_env_camera.h" +#include + +using namespace pragma::rendering::shader_graph; + +extern DLLCLIENT CEngine *c_engine; +std::shared_ptr PbrModule::g_defaultPbrDsg = {}; +size_t PbrModule::g_instanceCount = 0; +PbrModule::PbrModule(prosper::Shader &shader) : pragma::rendering::ShaderGraphModule {shader} +{ + m_pbrDescSetInfo = { + "PBR", + {prosper::DescriptorSetInfo::Binding {"IRRADIANCE_MAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit, prosper::PrDescriptorSetBindingFlags::Cubemap}, + prosper::DescriptorSetInfo::Binding {"PREFILTER_MAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit, prosper::PrDescriptorSetBindingFlags::Cubemap}, + prosper::DescriptorSetInfo::Binding {"BRDF_MAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit}}, + }; +} +PbrModule::~PbrModule() +{ + if(--g_instanceCount == 0) + g_defaultPbrDsg = nullptr; +} +void PbrModule::InitializeGfxPipelineDescriptorSets() +{ + m_shader.AddDescriptorSetGroup(m_pbrDescSetInfo); + if(!g_defaultPbrDsg) { + auto &context = c_engine->GetRenderContext(); + g_defaultPbrDsg = context.CreateDescriptorSetGroup(m_pbrDescSetInfo); + auto &dummyTex = context.GetDummyTexture(); + auto &dummyCubemapTex = context.GetDummyCubemapTexture(); + auto &ds = *g_defaultPbrDsg->GetDescriptorSet(0); + ds.SetBindingTexture(*dummyCubemapTex, umath::to_integral(PBRBinding::IrradianceMap)); + ds.SetBindingTexture(*dummyCubemapTex, umath::to_integral(PBRBinding::PrefilterMap)); + ds.SetBindingTexture(*dummyTex, umath::to_integral(PBRBinding::BRDFMap)); + } +} +void PbrModule::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const +{ + float iblStrength = 1.f; + auto *ds = GetReflectionProbeDescriptorSet(scene, iblStrength, inOutSceneFlags); + + shaderProcessor.GetCommandBuffer().RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, shaderProcessor.GetCurrentPipelineLayout(), m_pbrDescSetInfo.setIndex, *ds); +} +prosper::IDescriptorSet *PbrModule::GetReflectionProbeDescriptorSet(const pragma::CSceneComponent &scene, float &outIblStrength, ShaderGameWorld::SceneFlags &inOutSceneFlags) const +{ + auto &hCam = scene.GetActiveCamera(); + assert(hCam.valid()); + auto *dsPbr = CReflectionProbeComponent::FindDescriptorSetForClosestProbe(scene, hCam->GetEntity().GetPosition(), outIblStrength); + if(dsPbr == nullptr) // No reflection probe and therefore no IBL available. Fallback to non-IBL rendering. + { + dsPbr = &GetDefaultPbrDescriptorSet(); + inOutSceneFlags |= ShaderGameWorld::SceneFlags::NoIBL; + } + return dsPbr; +} +prosper::IDescriptorSet &PbrModule::GetDefaultPbrDescriptorSet() const { return *g_defaultPbrDsg->GetDescriptorSet(); } diff --git a/core/client/src/rendering/shader_graph/nodes/pbr.cpp b/core/client/src/rendering/shader_graph/nodes/pbr.cpp new file mode 100644 index 000000000..ea5198c64 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/pbr.cpp @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/pbr.hpp" + +using namespace pragma::rendering::shader_graph; + +PbrNode::PbrNode(const std::string_view &type) : Node {type} +{ + AddInput(IN_ALBEDO_COLOR, pragma::shadergraph::SocketType::Color, Vector3 {1.f, 1.f, 1.f}); + AddInput(IN_METALNESS, pragma::shadergraph::SocketType::Float, 0.f); + AddInput(IN_ROUGHNESS, pragma::shadergraph::SocketType::Float, 0.5f); + AddInput(IN_AMBIENT_OCCLUSION, pragma::shadergraph::SocketType::Float, 0.f); + + AddOutput(OUT_COLOR, pragma::shadergraph::SocketType::Color); + + AddModuleDependency("pbr"); +} + +std::string PbrNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + + auto inAc = gn.GetInputNameOrValue(IN_ALBEDO_COLOR); + auto inMetalness = gn.GetInputNameOrValue(IN_METALNESS); + auto inRoughness = gn.GetInputNameOrValue(IN_ROUGHNESS); + auto inAo = gn.GetInputNameOrValue(IN_AMBIENT_OCCLUSION); + + auto prefix = gn.GetBaseVarName() + "_"; + auto vA = prefix + "albedo"; + auto vUv = prefix + "uv"; + auto vDbg = prefix + "debugMode"; + auto vMat = prefix + "material"; + auto vEmission = prefix + "emissionFactor"; + auto vMatFlags = prefix + "matFlags"; + code << "vec4 " << vA << " = vec4(" << inAc << ",1);\n"; + code << "vec2 " << vUv << " = get_uv_coordinates();\n"; + code << "uint " << vDbg << " = 0;\n"; + code << "PbrMaterial " << vMat << ";\n"; + code << vMat << ".color = vec4(1,1,1,1);\n"; + code << vMat << ".metalnessFactor = " << inMetalness << ";\n"; + code << vMat << ".roughnessFactor = " << inRoughness << ";\n"; + code << vMat << ".aoFactor = " << inAo << ";\n"; + code << vMat << ".alphaMode = ALPHA_MODE_OPAQUE;\n"; + code << vMat << ".alphaCutoff = 0.5;\n"; + code << "vec3 " << vEmission << " = vec3(0,0,0);\n"; + code << "uint " << vMatFlags << " = 0;\n"; + code << gn.GetGlslOutputDeclaration(OUT_COLOR) << " = "; + code << "calc_pbr(" << vA << ", " << vUv << ", " << vDbg << ", " << vMat << ", " << vEmission << ", " << vMatFlags << ").rgb;\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shaders/world/c_shader_graph.cpp b/core/client/src/rendering/shaders/world/c_shader_graph.cpp index 236fc88f4..2e739f575 100644 --- a/core/client/src/rendering/shaders/world/c_shader_graph.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_graph.cpp @@ -13,6 +13,8 @@ #include "pragma/rendering/renderers/rasterization_renderer.hpp" #include "pragma/rendering/render_processor.hpp" #include "pragma/rendering/shader_material/shader_material.hpp" +#include "pragma/rendering/shader_graph/manager.hpp" +#include "pragma/rendering/shader_graph/module.hpp" #include "pragma/model/vk_mesh.h" #include "pragma/model/c_modelmesh.h" #include @@ -35,15 +37,55 @@ using namespace pragma; ShaderGraph::ShaderGraph(prosper::IPrContext &context, const std::string &identifier, const std::string &fsShader) : ShaderGameWorldLightingPass {context, identifier, "programs/scene/textured", fsShader} {} +ShaderGraph::~ShaderGraph() {} + void ShaderGraph::UpdateRenderFlags(CModelSubMesh &mesh, SceneFlags &inOutFlags) { ShaderGameWorldLightingPass::UpdateRenderFlags(mesh, inOutFlags); - inOutFlags |= m_extRenderFlags; + for(auto &mod : m_modules) + mod->UpdateRenderFlags(mesh, inOutFlags); +} +void ShaderGraph::InitializeGfxPipelineDescriptorSets() +{ + ShaderGameWorldLightingPass::InitializeGfxPipelineDescriptorSets(); + for(auto &mod : m_modules) + mod->InitializeGfxPipelineDescriptorSets(); +} + +void ShaderGraph::ClearShaderResources() +{ + m_modules.clear(); + ShaderGameWorldLightingPass::ClearShaderResources(); +} + +void ShaderGraph::InitializeShaderResources() +{ + auto &graphManager = c_engine->GetShaderGraphManager(); + auto graphData = graphManager.GetGraph(GetIdentifier()); + if(graphData) { + auto &graph = graphData->GetGraph(); + std::unordered_set moduleNames; + for(auto &node : graph->GetNodes()) { + auto &deps = (*node)->GetModuleDependencies(); + moduleNames.reserve(moduleNames.size() + deps.size()); + moduleNames.insert(deps.begin(), deps.end()); + } + for(auto &modName : moduleNames) { + auto mod = graphManager.GetModuleManager().CreateModule(modName, *this); + if(mod) + m_modules.emplace_back(std::move(mod)); + } + } + + ShaderGameWorldLightingPass::InitializeShaderResources(); } -void ShaderGraph::InitializeGfxPipelineDescriptorSets() { ShaderGameWorldLightingPass::InitializeGfxPipelineDescriptorSets(); } void ShaderGraph::InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) { + + // If graph has "pbr" module, pbr descriptor set should be added + //prosper::DescriptorSetInfo + ShaderGameWorldLightingPass::InitializeMaterialData(mat, shaderMat, inOutMatData); auto &data = mat.GetDataBlock(); float specularFactor; @@ -60,29 +102,17 @@ std::shared_ptr ShaderGraph::InitializeMaterialDes void ShaderGraph::OnPipelinesInitialized() { ShaderGameWorldLightingPass::OnPipelinesInitialized(); } void ShaderGraph::InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) { ShaderGameWorldLightingPass::InitializeGfxPipeline(pipelineInfo, pipelineIdx); } -// - -void ShaderGraph::RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const -{ - outIblStrength = 1.f; - std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsLights, &dsShadows}; - - static const std::vector dynamicOffsets {}; - shaderProcessor.GetCommandBuffer().RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, shaderProcessor.GetCurrentPipelineLayout(), GetSceneDescriptorSetIndex(), descSets, dynamicOffsets); -} - void ShaderGraph::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { - auto iblStrength = 1.f; - RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows, inOutSceneFlags, iblStrength); - ShaderGameWorldLightingPass::PushConstants pushConstants {}; pushConstants.Initialize(); pushConstants.debugMode = scene.GetDebugMode(); - pushConstants.reflectionProbeIntensity = iblStrength; + pushConstants.reflectionProbeIntensity = 1.f; pushConstants.flags = inOutSceneFlags; pushConstants.drawOrigin = drawOrigin; shaderProcessor.GetCommandBuffer().RecordPushConstants(shaderProcessor.GetCurrentPipelineLayout(), prosper::ShaderStageFlags::VertexBit | prosper::ShaderStageFlags::FragmentBit, 0u, sizeof(pushConstants), &pushConstants); + + for(auto &mod : m_modules) + mod->RecordBindScene(shaderProcessor, scene, renderer, inOutSceneFlags); } From 90aa88710e8000c79b9b38595bb0135f71f4a7cf Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 25 Nov 2024 09:55:01 +0100 Subject: [PATCH 25/64] build: update submodules --- build_scripts/build.py | 2 +- build_scripts/scripts/external_libs.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index 80e5d33f0..5f4e1a71c 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -1136,7 +1136,7 @@ def download_addon(name,addonName,url,commitId=None): curDir = os.getcwd() if not skip_repository_updates: if with_pfm: - download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","7492a21fc643fa831dc45bfcb401bd7b4ecdc2f1") + download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","f41835d289e2b2da604a3f598590f7ffaaabbf9f") download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","a9ea4820f03be250bdf1e6951dad313561b75b17") if with_vr: diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 4316a54ad..d3e5bb4be 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","6e5238ef5bde5aafabdc6711d55a5a336c5aa13f") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","c1eaf0a54f836a5b86b43770f3e37fa1d5e56d9f") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") @@ -32,7 +32,7 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") -get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","610d417e369a7a7408ad29949e72f81aab74456e") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","30b7e7bbf06b786340e05ee5fde80842dfaee633") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") From 5654694e9c730b5c4124b84ffe2f77b2bf939c25 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Tue, 26 Nov 2024 08:27:09 +0100 Subject: [PATCH 26/64] feat: merge light descriptor set bindings into renderer descriptor set This opens up another descriptor set slot to be used by custom shaders. --- assets/shaders/common/inputs/csm.glsl | 2 +- .../lighting/inputs/light_sources.glsl | 8 ++-- .../lighting/inputs/vis_light_buffer.glsl | 2 +- .../compute/forwardp_light_culling.comp | 4 +- .../c_rasterization_renderer_component.hpp | 2 - .../pragma/rendering/shaders/c_shader_lua.hpp | 2 +- .../rendering/shaders/c_shader_shadow.hpp | 3 +- .../particles/c_shader_particle_2d_base.hpp | 4 +- .../particles/c_shader_particle_blob.hpp | 3 +- .../rendering/shaders/world/c_shader_eye.hpp | 2 +- .../rendering/shaders/world/c_shader_glow.hpp | 4 +- .../shaders/world/c_shader_graph.hpp | 2 +- .../rendering/shaders/world/c_shader_pbr.hpp | 4 +- .../shaders/world/c_shader_prepass.hpp | 2 +- .../shaders/world/c_shader_scene.hpp | 37 +++++++++++++++---- .../shaders/world/c_shader_skybox.hpp | 3 +- .../shaders/world/c_shader_textured.hpp | 4 +- .../c_rasterization_renderer_component.cpp | 21 +++++------ core/client/src/lua/c_luaclass.cpp | 1 - .../renderers/c_particle_mod_blob.cpp | 3 +- .../renderers/c_particle_mod_sprite.cpp | 3 +- .../c_particle_renderer_animated_sprites.cpp | 3 +- .../c_particle_renderer_sprite_trail.cpp | 3 +- core/client/src/rendering/c_forwardplus.cpp | 4 +- .../client/src/rendering/shader_processor.cpp | 4 +- .../c_shader_forwardp_light_culling.cpp | 4 +- .../src/rendering/shaders/c_shader_lua.cpp | 4 +- .../src/rendering/shaders/c_shader_shadow.cpp | 3 +- .../particles/c_shader_particle_2d_base.cpp | 7 +--- .../particles/c_shader_particle_blob.cpp | 6 +-- .../rendering/shaders/world/c_shader_eye.cpp | 4 +- .../rendering/shaders/world/c_shader_glow.cpp | 8 ++-- .../shaders/world/c_shader_graph.cpp | 2 +- .../rendering/shaders/world/c_shader_pbr.cpp | 8 ++-- .../shaders/world/c_shader_prepass.cpp | 2 +- .../shaders/world/c_shader_scene.cpp | 11 ++---- .../shaders/world/c_shader_skybox.cpp | 3 +- .../shaders/world/c_shader_textured.cpp | 7 +--- 38 files changed, 97 insertions(+), 102 deletions(-) diff --git a/assets/shaders/common/inputs/csm.glsl b/assets/shaders/common/inputs/csm.glsl index 994fa4ba2..86d366281 100644 --- a/assets/shaders/common/inputs/csm.glsl +++ b/assets/shaders/common/inputs/csm.glsl @@ -12,7 +12,7 @@ layout(std140, LAYOUT_ID(RENDER_SETTINGS, CSM_DATA)) uniform CSM } u_csm; #ifdef GLS_FRAGMENT_SHADER -layout(LAYOUT_ID(LIGHTS, CSM_MAPS)) uniform sampler2D csmTextures[MAX_CSM_CASCADES]; +layout(LAYOUT_ID(RENDERER, CSM_MAPS)) uniform sampler2D csmTextures[MAX_CSM_CASCADES]; int get_csm_cascade_index() { diff --git a/assets/shaders/lighting/inputs/light_sources.glsl b/assets/shaders/lighting/inputs/light_sources.glsl index 9fa90b6e2..8a612e60c 100644 --- a/assets/shaders/lighting/inputs/light_sources.glsl +++ b/assets/shaders/lighting/inputs/light_sources.glsl @@ -20,16 +20,16 @@ struct ShadowData { #if USE_LIGHT_SOURCE_UNIFORM_BUFFER == 0 -layout(std430, LAYOUT_ID(LIGHTS, LIGHT_BUFFERS)) readonly buffer LightBuffer { LightSourceData data[]; } +layout(std430, LAYOUT_ID(RENDERER, LIGHT_BUFFERS)) readonly buffer LightBuffer { LightSourceData data[]; } lightBuffer; -layout(std430, LAYOUT_ID(LIGHTS, SHADOW_BUFFERS)) readonly buffer ShadowBuffer { ShadowData data[]; } +layout(std430, LAYOUT_ID(RENDERER, SHADOW_BUFFERS)) readonly buffer ShadowBuffer { ShadowData data[]; } shadowBuffer; #else -layout(std140, LAYOUT_ID(LIGHTS, LIGHT_BUFFERS)) uniform LightBuffer { LightSourceData data[MAX_SCENE_LIGHTS]; } +layout(std140, LAYOUT_ID(RENDERER, LIGHT_BUFFERS)) uniform LightBuffer { LightSourceData data[MAX_SCENE_LIGHTS]; } lightBuffer; -layout(std140, LAYOUT_ID(LIGHTS, SHADOW_BUFFERS)) uniform ShadowBuffer { ShadowData data[MAX_ACTIVE_SHADOW_SOURCES]; } +layout(std140, LAYOUT_ID(RENDERER, SHADOW_BUFFERS)) uniform ShadowBuffer { ShadowData data[MAX_ACTIVE_SHADOW_SOURCES]; } shadowBuffer; #endif diff --git a/assets/shaders/lighting/inputs/vis_light_buffer.glsl b/assets/shaders/lighting/inputs/vis_light_buffer.glsl index 75ca0feb4..b6f52092b 100644 --- a/assets/shaders/lighting/inputs/vis_light_buffer.glsl +++ b/assets/shaders/lighting/inputs/vis_light_buffer.glsl @@ -4,7 +4,7 @@ struct VisibleIndex { int index; }; -layout(std430, LAYOUT_ID(LIGHTS, VISIBLE_LIGHT_TILE_INDEX_BUFFER)) buffer VisibleLightTileIndicesBuffer { VisibleIndex data[]; } +layout(std430, LAYOUT_ID(RENDERER, VISIBLE_LIGHT_TILE_INDEX_BUFFER)) buffer VisibleLightTileIndicesBuffer { VisibleIndex data[]; } visibleLightTileIndicesBuffer; #endif diff --git a/assets/shaders/programs/compute/forwardp_light_culling.comp b/assets/shaders/programs/compute/forwardp_light_culling.comp index 6f37c0470..6eeac02a2 100644 --- a/assets/shaders/programs/compute/forwardp_light_culling.comp +++ b/assets/shaders/programs/compute/forwardp_light_culling.comp @@ -12,7 +12,7 @@ #include "/functions/fs_linearize_depth.glsl" #include "/math/intersection.glsl" -layout(std430, LAYOUT_ID(LIGHTS, VISIBLE_LIGHT_INDEX_BUFFER)) buffer VisibleLightIndicesBuffer { uint visibleBits[]; } +layout(std430, LAYOUT_ID(RENDERER, VISIBLE_LIGHT_INDEX_BUFFER)) buffer VisibleLightIndicesBuffer { uint visibleBits[]; } visibleLightIndicesBuffer; layout(LAYOUT_PUSH_CONSTANTS()) uniform LightInfo @@ -23,7 +23,7 @@ layout(LAYOUT_PUSH_CONSTANTS()) uniform LightInfo } u_lightInfo; -layout(LAYOUT_ID(LIGHTS, DEPTH_MAP)) uniform sampler2D u_sceneDepth; +layout(LAYOUT_ID(RENDERER, DEPTH_MAP)) uniform sampler2D u_sceneDepth; // Specialization constants not supported on some GPUs? // layout(constant_id = 1) const uint FORWARDP_TILE_SIZE = 16; diff --git a/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp b/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp index b9a91daa3..29e04cd34 100644 --- a/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp +++ b/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp @@ -202,7 +202,6 @@ namespace pragma { // rendering has finished. void SetFrameDepthBufferSamplingRequired(); - prosper::IDescriptorSet *GetLightSourceDescriptorSet() const; prosper::IDescriptorSet *GetLightSourceDescriptorSetCompute() const; prosper::Shader *GetWireframeShader() const; @@ -268,7 +267,6 @@ namespace pragma { LightMapInfo m_lightMapInfo = {}; bool m_bFrameDepthBufferSamplingRequired = false; - std::shared_ptr m_dsgLights; std::shared_ptr m_dsgLightsCompute; std::vector m_visLightSources; diff --git a/core/client/include/pragma/rendering/shaders/c_shader_lua.hpp b/core/client/include/pragma/rendering/shaders/c_shader_lua.hpp index b36617bb6..6b0b9062b 100644 --- a/core/client/include/pragma/rendering/shaders/c_shader_lua.hpp +++ b/core/client/include/pragma/rendering/shaders/c_shader_lua.hpp @@ -454,7 +454,7 @@ namespace pragma { virtual void SetPipelineCount(uint32_t count) override { ShaderGameWorldLightingPass::SetPipelineCount(count); } virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; virtual std::shared_ptr InitializeMaterialDescriptorSet(CMaterial &mat) override; virtual void InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) override; void SetPushConstants(DataStream dsPushConstants); diff --git a/core/client/include/pragma/rendering/shaders/c_shader_shadow.hpp b/core/client/include/pragma/rendering/shaders/c_shader_shadow.hpp index 5b1f46abe..d990425af 100644 --- a/core/client/include/pragma/rendering/shaders/c_shader_shadow.hpp +++ b/core/client/include/pragma/rendering/shaders/c_shader_shadow.hpp @@ -66,7 +66,7 @@ namespace pragma { // virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; virtual void RecordSceneFlags(rendering::ShaderProcessor &shaderProcessor, SceneFlags sceneFlags) const override; virtual void RecordBindLight(rendering::ShaderProcessor &shaderProcessor, CLightComponent &light, uint32_t layerId) const override; virtual void RecordAlphaCutoff(rendering::ShaderProcessor &shaderProcessor, float alphaCutoff) const override; @@ -85,7 +85,6 @@ namespace pragma { private: virtual uint32_t GetRenderSettingsDescriptorSetIndex() const override; virtual uint32_t GetCameraDescriptorSetIndex() const override; - virtual uint32_t GetLightDescriptorSetIndex() const override; virtual uint32_t GetInstanceDescriptorSetIndex() const override; virtual void GetVertexAnimationPushConstantInfo(uint32_t &offset) const override; }; diff --git a/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_2d_base.hpp b/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_2d_base.hpp index f1ec29f44..f1f3fa9dc 100644 --- a/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_2d_base.hpp +++ b/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_2d_base.hpp @@ -36,7 +36,6 @@ namespace pragma { static prosper::DescriptorSetInfo DESCRIPTOR_SET_SCENE; static prosper::DescriptorSetInfo DESCRIPTOR_SET_RENDERER; static prosper::DescriptorSetInfo DESCRIPTOR_SET_RENDER_SETTINGS; - static prosper::DescriptorSetInfo DESCRIPTOR_SET_LIGHTS; static prosper::DescriptorSetInfo DESCRIPTOR_SET_SHADOWS; static constexpr auto VERTEX_COUNT = 6u; @@ -73,7 +72,7 @@ namespace pragma { virtual bool RecordDraw(prosper::ShaderBindState &bindState, pragma::CSceneComponent &scene, const CRasterizationRendererComponent &renderer, const CParticleSystemComponent &ps, CParticleSystemComponent::OrientationType orientationType, ParticleRenderFlags renderFlags); std::optional RecordBeginDraw(prosper::ShaderBindState &bindState, CParticleSystemComponent &pSys, ParticleRenderFlags renderFlags, RecordFlags recordFlags = RecordFlags::RenderPassTargetAsViewportAndScissor); virtual bool RecordBindScene(prosper::ICommandBuffer &cmd, const prosper::IShaderPipelineLayout &layout, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows) const; + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows) const; virtual uint32_t GetSceneDescriptorSetIndex() const; void GetParticleSystemOrientationInfo(const Mat4 &matrix, const CParticleSystemComponent &particle, CParticleSystemComponent::OrientationType orientationType, Vector3 &up, Vector3 &right, float &nearZ, float &farZ, const Material *material = nullptr, float camNearZ = 0.f, @@ -89,7 +88,6 @@ namespace pragma { virtual bool RecordParticleMaterial(prosper::ShaderBindState &bindState, const CRasterizationRendererComponent &renderer, const CParticleSystemComponent &ps) const; virtual uint32_t GetRenderSettingsDescriptorSetIndex() const override; - virtual uint32_t GetLightDescriptorSetIndex() const override; virtual uint32_t GetCameraDescriptorSetIndex() const override; virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override; virtual void InitializeShaderResources() override; diff --git a/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_blob.hpp b/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_blob.hpp index 6255176c6..66892c609 100644 --- a/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_blob.hpp +++ b/core/client/include/pragma/rendering/shaders/particles/c_shader_particle_blob.hpp @@ -26,7 +26,6 @@ namespace pragma { static prosper::DescriptorSetInfo DESCRIPTOR_SET_SCENE; static prosper::DescriptorSetInfo DESCRIPTOR_SET_RENDERER; static prosper::DescriptorSetInfo DESCRIPTOR_SET_RENDER_SETTINGS; - static prosper::DescriptorSetInfo DESCRIPTOR_SET_LIGHTS; static prosper::DescriptorSetInfo DESCRIPTOR_SET_SHADOWS; static prosper::DescriptorSetInfo DESCRIPTOR_SET_PBR; @@ -37,7 +36,7 @@ namespace pragma { bool RecordDraw(prosper::ShaderBindState &bindState, pragma::CSceneComponent &scene, const CRasterizationRendererComponent &renderer, const CParticleSystemComponent &ps, CParticleSystemComponent::OrientationType orientationType, ParticleRenderFlags renderFlags, prosper::IBuffer &blobIndexBuffer, prosper::IDescriptorSet &dsParticles, uint32_t particleBufferOffset); virtual bool RecordBindScene(prosper::ICommandBuffer &cmd, const prosper::IShaderPipelineLayout &layout, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows) const override; + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows) const override; virtual std::shared_ptr InitializeMaterialDescriptorSet(CMaterial &mat) override; protected: virtual void GetShaderPreprocessorDefinitions(std::unordered_map &outDefinitions, std::string &outPrefixCode) override; diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_eye.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_eye.hpp index 9939ce68f..5443bddb1 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_eye.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_eye.hpp @@ -35,7 +35,7 @@ namespace pragma { // virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; virtual bool OnRecordDrawMesh(rendering::ShaderProcessor &shaderProcessor, CModelSubMesh &mesh) const override; virtual bool IsLegacyShader() const { return false; } protected: diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_glow.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_glow.hpp index 1379cd5f0..bb21058d3 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_glow.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_glow.hpp @@ -47,7 +47,7 @@ namespace pragma { // virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; static bool BindDescriptorSetTexture(Material &mat, prosper::IDescriptorSet &ds, TextureInfo *texInfo, uint32_t bindingIndex, const std::string &defaultTexName, Texture **optOutTex = nullptr); static bool BindDescriptorSetTexture(Material &mat, prosper::IDescriptorSet &ds, TextureInfo *texInfo, uint32_t bindingIndex, Texture *optDefaultTex = nullptr); @@ -56,7 +56,7 @@ namespace pragma { using ShaderGameWorldLightingPass::RecordDraw; virtual void InitializeRenderPass(std::shared_ptr &outRenderPass, uint32_t pipelineIdx) override; void RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const; + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const; virtual void OnPipelinesInitialized() override; virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override; virtual void UpdateRenderFlags(CModelSubMesh &mesh, SceneFlags &inOutFlags) override; diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp index f175d0940..ac86283e3 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp @@ -21,7 +21,7 @@ namespace pragma { virtual ~ShaderGraph() override; virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; protected: using ShaderGameWorldLightingPass::RecordDraw; virtual void OnPipelinesInitialized() override; diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_pbr.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_pbr.hpp index 335771a02..f781fd5dc 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_pbr.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_pbr.hpp @@ -45,13 +45,13 @@ namespace pragma { // virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; prosper::IDescriptorSet *GetReflectionProbeDescriptorSet(const pragma::CSceneComponent &scene, float &outIblStrength, ShaderGameWorld::SceneFlags &inOutSceneFlags) const; protected: using ShaderGameWorldLightingPass::RecordDraw; void RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const; + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const; virtual void OnPipelinesInitialized() override; virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override; virtual void InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) override; diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_prepass.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_prepass.hpp index f33be5660..27bda12c5 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_prepass.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_prepass.hpp @@ -63,7 +63,7 @@ namespace pragma { // virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; virtual void RecordAlphaCutoff(rendering::ShaderProcessor &shaderProcessor, float alphaCutoff) const override; virtual bool RecordBindMaterial(rendering::ShaderProcessor &shaderProcessor, CMaterial &mat) const override; protected: diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_scene.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_scene.hpp index d1ef88734..ecdc864b3 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_scene.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_scene.hpp @@ -39,11 +39,31 @@ namespace pragma { static prosper::SampleCountFlags RENDER_PASS_SAMPLES; static void SetRenderPassSampleCount(prosper::SampleCountFlags samples); - enum class SceneBinding : uint32_t { Camera = 0u, RenderSettings }; + enum class SceneBinding : uint32_t { + Camera = 0u, + RenderSettings, + }; + + enum class RendererBinding : uint32_t { + Renderer = 0u, + SSAOMap, + + LightBuffers, + TileVisLightIndexBuffer, + ShadowData, + CSM, - enum class RendererBinding : uint32_t { Renderer = 0u, SSAOMap, LightMapDiffuse, LightMapDiffuseIndirect, LightMapDominantDirection }; + LightMapDiffuse, + LightMapDiffuseIndirect, + LightMapDominantDirection, + }; - enum class RenderSettingsBinding : uint32_t { Debug = 0u, Time, CSMData, GlobalInstance }; + enum class RenderSettingsBinding : uint32_t { + Debug = 0u, + Time, + CSMData, + GlobalInstance, + }; enum class DebugFlags : uint32_t { None = 0u, @@ -80,10 +100,14 @@ namespace pragma { class DLLCLIENT ShaderSceneLit : public ShaderScene { public: - static prosper::DescriptorSetInfo DESCRIPTOR_SET_LIGHTS; static prosper::DescriptorSetInfo DESCRIPTOR_SET_SHADOWS; - enum class LightBinding : uint32_t { LightBuffers = 0u, TileVisLightIndexBuffer, ShadowData, CSM }; + enum class LightBinding : uint32_t { + LightBuffers = 0u, + TileVisLightIndexBuffer, + ShadowData, + CSM, + }; enum class ShadowBinding : uint32_t { ShadowMaps = 0u, @@ -97,7 +121,6 @@ namespace pragma { int32_t count; }; #pragma pack(pop) - virtual uint32_t GetLightDescriptorSetIndex() const = 0; protected: ShaderSceneLit(prosper::IPrContext &context, const std::string &identifier, const std::string &vsShader, const std::string &fsShader, const std::string &gsShader = ""); }; @@ -207,7 +230,7 @@ namespace pragma { // Note: All recording functions are called in a multi-threaded environment! Handle with care! virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, SceneFlags &inOutSceneFlags) const { } virtual bool RecordBindEntity(rendering::ShaderProcessor &shaderProcessor, CRenderComponent &renderC, prosper::IShaderPipelineLayout &layout, uint32_t entityInstanceDescriptorSetIndex) const; diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_skybox.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_skybox.hpp index d1949c062..bf6b62abe 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_skybox.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_skybox.hpp @@ -32,7 +32,7 @@ namespace pragma { // virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; virtual bool RecordBindEntity(rendering::ShaderProcessor &shaderProcessor, CRenderComponent &renderC, prosper::IShaderPipelineLayout &layout, uint32_t entityInstanceDescriptorSetIndex) const override; virtual void RecordSceneFlags(rendering::ShaderProcessor &shaderProcessor, SceneFlags sceneFlags) const override {} virtual void RecordClipPlane(rendering::ShaderProcessor &shaderProcessor, const Vector4 &clipPlane) const override {} @@ -44,7 +44,6 @@ namespace pragma { virtual uint32_t GetRendererDescriptorSetIndex() const override; virtual uint32_t GetRenderSettingsDescriptorSetIndex() const override; virtual uint32_t GetCameraDescriptorSetIndex() const override; - virtual uint32_t GetLightDescriptorSetIndex() const override; virtual uint32_t GetInstanceDescriptorSetIndex() const override; virtual uint32_t GetSceneDescriptorSetIndex() const override; virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override; diff --git a/core/client/include/pragma/rendering/shaders/world/c_shader_textured.hpp b/core/client/include/pragma/rendering/shaders/world/c_shader_textured.hpp index f4e6bb3d2..22752b9bb 100644 --- a/core/client/include/pragma/rendering/shaders/world/c_shader_textured.hpp +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_textured.hpp @@ -128,7 +128,6 @@ namespace pragma { static prosper::DescriptorSetInfo DESCRIPTOR_SET_SCENE; static prosper::DescriptorSetInfo DESCRIPTOR_SET_RENDERER; static prosper::DescriptorSetInfo DESCRIPTOR_SET_RENDER_SETTINGS; - static prosper::DescriptorSetInfo DESCRIPTOR_SET_LIGHTS; static prosper::DescriptorSetInfo DESCRIPTOR_SET_SHADOWS; static bool InitializeMaterialBuffer(prosper::IDescriptorSet &descSet, CMaterial &mat, const pragma::rendering::shader_material::ShaderMaterialData &matData, uint32_t bindingIdx); @@ -176,7 +175,6 @@ namespace pragma { virtual uint32_t GetRendererDescriptorSetIndex() const override; virtual uint32_t GetInstanceDescriptorSetIndex() const override; virtual uint32_t GetRenderSettingsDescriptorSetIndex() const override; - virtual uint32_t GetLightDescriptorSetIndex() const override; virtual uint32_t GetPassPipelineIndexStartOffset(rendering::PassType passType) const override; std::optional FindPipelineIndex(rendering::PassType passType, GameShaderSpecialization specialization, GameShaderSpecializationConstantFlag specializationFlags) const; virtual GameShaderSpecializationConstantFlag GetMaterialPipelineSpecializationRequirements(CMaterial &mat) const; @@ -187,7 +185,7 @@ namespace pragma { virtual GameShaderSpecializationConstantFlag GetBaseSpecializationFlags() const; virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; virtual bool IsUsingLightmaps() const override { return true; } bool IsDepthPrepassEnabled() const; void SetDepthPrepassEnabled(bool enabled) { m_depthPrepassEnabled = enabled; } diff --git a/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp b/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp index 28aa98918..7ac642766 100644 --- a/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp +++ b/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp @@ -114,7 +114,6 @@ CRasterizationRendererComponent::CRasterizationRendererComponent(BaseEntity &ent { m_whShaderWireframe = c_engine->GetShader("wireframe"); - InitializeLightDescriptorSets(); InitializeCommandBufferGroups(); prosper::util::BufferCreateInfo bufCreateInfo {}; @@ -129,6 +128,8 @@ CRasterizationRendererComponent::CRasterizationRendererComponent(BaseEntity &ent m_descSetGroupRenderer = shaderPbr->CreateDescriptorSetGroup(pragma::ShaderPBR::DESCRIPTOR_SET_RENDERER.setIndex); m_descSetGroupRenderer->GetDescriptorSet()->SetBindingUniformBuffer(*m_rendererBuffer, umath::to_integral(pragma::ShaderScene::RendererBinding::Renderer)); } + + InitializeLightDescriptorSets(); } CRasterizationRendererComponent::~CRasterizationRendererComponent() @@ -138,7 +139,6 @@ CRasterizationRendererComponent::~CRasterizationRendererComponent() renderContext.KeepResourceAliveUntilPresentationComplete(m_shadowCommandBufferGroup); renderContext.KeepResourceAliveUntilPresentationComplete(m_lightingCommandBufferGroup); renderContext.KeepResourceAliveUntilPresentationComplete(m_descSetGroupFogOverride); - renderContext.KeepResourceAliveUntilPresentationComplete(m_dsgLights); renderContext.KeepResourceAliveUntilPresentationComplete(m_dsgLightsCompute); renderContext.KeepResourceAliveUntilPresentationComplete(m_rendererBuffer); renderContext.KeepResourceAliveUntilPresentationComplete(m_descSetGroupRenderer); @@ -184,7 +184,6 @@ void CRasterizationRendererComponent::UpdateRendererBuffer(std::shared_ptrGetDescriptorSet() : nullptr; } prosper::IDescriptorSet *CRasterizationRendererComponent::GetRendererDescriptorSet() const { return m_descSetGroupRenderer->GetDescriptorSet(); } -prosper::IDescriptorSet *CRasterizationRendererComponent::GetLightSourceDescriptorSet() const { return m_dsgLights->GetDescriptorSet(); } prosper::IDescriptorSet *CRasterizationRendererComponent::GetLightSourceDescriptorSetCompute() const { return m_dsgLightsCompute->GetDescriptorSet(); } void CRasterizationRendererComponent::InitializeCommandBufferGroups() @@ -198,16 +197,16 @@ void CRasterizationRendererComponent::InitializeCommandBufferGroups() void CRasterizationRendererComponent::InitializeLightDescriptorSets() { - if(pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_LIGHTS.IsValid()) { + if(pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_RENDERER.IsValid()) { auto &bufLightSources = pragma::CLightComponent::GetGlobalRenderBuffer(); auto &bufShadowData = pragma::CLightComponent::GetGlobalShadowBuffer(); - m_dsgLights = c_engine->GetRenderContext().CreateDescriptorSetGroup(pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_LIGHTS); + auto &ds = *GetRendererDescriptorSet(); #if USE_LIGHT_SOURCE_UNIFORM_BUFFER == 1 - m_dsgLights->GetDescriptorSet()->SetBindingUniformBuffer(const_cast(bufLightSources), umath::to_integral(pragma::ShaderGameWorldLightingPass::LightBinding::LightBuffers)); - m_dsgLights->GetDescriptorSet()->SetBindingUniformBuffer(const_cast(bufShadowData), umath::to_integral(pragma::ShaderGameWorldLightingPass::LightBinding::ShadowData)); + ds.SetBindingUniformBuffer(const_cast(bufLightSources), umath::to_integral(pragma::ShaderGameWorldLightingPass::RendererBinding::LightBuffers)); + ds.SetBindingUniformBuffer(const_cast(bufShadowData), umath::to_integral(pragma::ShaderGameWorldLightingPass::RendererBinding::ShadowData)); #else - m_dsgLights->GetDescriptorSet()->SetBindingStorageBuffer(const_cast(bufLightSources), umath::to_integral(pragma::ShaderGameWorldLightingPass::LightBinding::LightBuffers)); - m_dsgLights->GetDescriptorSet()->SetBindingStorageBuffer(const_cast(bufShadowData), umath::to_integral(pragma::ShaderGameWorldLightingPass::LightBinding::ShadowData)); + ds.SetBindingStorageBuffer(const_cast(bufLightSources), umath::to_integral(pragma::ShaderGameWorldLightingPass::RendererBinding::LightBuffers)); + ds.SetBindingStorageBuffer(const_cast(bufShadowData), umath::to_integral(pragma::ShaderGameWorldLightingPass::RendererBinding::ShadowData)); #endif m_dsgLightsCompute = c_engine->GetRenderContext().CreateDescriptorSetGroup(pragma::ShaderForwardPLightCulling::DESCRIPTOR_SET_LIGHTS); @@ -223,7 +222,7 @@ void CRasterizationRendererComponent::InitializeLightDescriptorSets() void CRasterizationRendererComponent::UpdateCSMDescriptorSet(pragma::CLightDirectionalComponent &lightSource) { - auto *dsLights = GetLightSourceDescriptorSet(); + auto *dsLights = GetRendererDescriptorSet(); if(dsLights == nullptr) return; auto *pShadowMap = lightSource.GetShadowMap(); @@ -232,7 +231,7 @@ void CRasterizationRendererComponent::UpdateCSMDescriptorSet(pragma::CLightDirec return; auto numLayers = pShadowMap->GetLayerCount(); for(auto i = decltype(numLayers) {0}; i < numLayers; ++i) { - dsLights->SetBindingArrayTexture(*texture, umath::to_integral(pragma::ShaderSceneLit::LightBinding::CSM), i, i); + dsLights->SetBindingArrayTexture(*texture, umath::to_integral(pragma::ShaderSceneLit::RendererBinding::CSM), i, i); } } diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 3cdd06a6a..4c70008be 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -785,7 +785,6 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) modShader[defShaderScene]; auto defShaderSceneLit = luabind::class_>("SceneLit3D"); - defShaderSceneLit.def("GetLightDescriptorSetIndex", &pragma::ShaderSceneLit::GetLightDescriptorSetIndex); modShader[defShaderSceneLit]; auto defShaderEntity = luabind::class_>("ShaderEntity"); diff --git a/core/client/src/particlesystem/renderers/c_particle_mod_blob.cpp b/core/client/src/particlesystem/renderers/c_particle_mod_blob.cpp index c351ce299..09bad119b 100644 --- a/core/client/src/particlesystem/renderers/c_particle_mod_blob.cpp +++ b/core/client/src/particlesystem/renderers/c_particle_mod_blob.cpp @@ -481,9 +481,8 @@ void CParticleRendererBlob::RecordRender(prosper::ICommandBuffer &drawCmd, pragm auto *dsScene = scene.GetCameraDescriptorSetGraphics(); auto *dsRenderer = renderer.GetRendererDescriptorSet(); auto &dsRenderSettings = c_game->GetGlobalRenderSettingsDescriptorSet(); - auto *dsLights = renderer.GetLightSourceDescriptorSet(); auto *dsShadows = pragma::CShadowComponent::GetDescriptorSet(); - shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsLights, *dsShadows); + shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsShadows); shader->RecordDraw(bindState, scene, renderer, *m_particleSystem, m_particleSystem->GetOrientationType(), renderFlags, blobIndexBuffer, *s_dsParticles->GetDescriptorSet(), m_particleSystem->GetParticleBuffer()->GetStartOffset()); shader->RecordEndDraw(bindState); } diff --git a/core/client/src/particlesystem/renderers/c_particle_mod_sprite.cpp b/core/client/src/particlesystem/renderers/c_particle_mod_sprite.cpp index 685be68a8..4c7f26f8a 100644 --- a/core/client/src/particlesystem/renderers/c_particle_mod_sprite.cpp +++ b/core/client/src/particlesystem/renderers/c_particle_mod_sprite.cpp @@ -67,9 +67,8 @@ void CParticleRendererSprite::RecordRender(prosper::ICommandBuffer &drawCmd, pra auto *dsScene = scene.GetCameraDescriptorSetGraphics(); auto *dsRenderer = renderer.GetRendererDescriptorSet(); auto &dsRenderSettings = c_game->GetGlobalRenderSettingsDescriptorSet(); - auto *dsLights = renderer.GetLightSourceDescriptorSet(); auto *dsShadows = pragma::CShadowComponent::GetDescriptorSet(); - shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsLights, *dsShadows); + shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsShadows); shader->RecordDraw(bindState, scene, renderer, *m_particleSystem, (m_rotationalBuffer != nullptr && m_rotationalBuffer->ShouldRotationAlignVelocity()) ? pragma::CParticleSystemComponent::OrientationType::Velocity : m_particleSystem->GetOrientationType(), renderFlags); shader->RecordEndDraw(bindState); } diff --git a/core/client/src/particlesystem/renderers/c_particle_renderer_animated_sprites.cpp b/core/client/src/particlesystem/renderers/c_particle_renderer_animated_sprites.cpp index e77959eba..1a468307e 100644 --- a/core/client/src/particlesystem/renderers/c_particle_renderer_animated_sprites.cpp +++ b/core/client/src/particlesystem/renderers/c_particle_renderer_animated_sprites.cpp @@ -53,9 +53,8 @@ void CParticleRendererAnimatedSprites::RecordRender(prosper::ICommandBuffer &dra auto *dsScene = scene.GetCameraDescriptorSetGraphics(); auto *dsRenderer = renderer.GetRendererDescriptorSet(); auto &dsRenderSettings = c_game->GetGlobalRenderSettingsDescriptorSet(); - auto *dsLights = renderer.GetLightSourceDescriptorSet(); auto *dsShadows = pragma::CShadowComponent::GetDescriptorSet(); - shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsLights, *dsShadows); + shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsShadows); shader->RecordDraw(bindState, scene, renderer, *m_particleSystem, m_particleSystem->GetOrientationType(), renderFlags); shader->RecordEndDraw(bindState); } diff --git a/core/client/src/particlesystem/renderers/c_particle_renderer_sprite_trail.cpp b/core/client/src/particlesystem/renderers/c_particle_renderer_sprite_trail.cpp index 68861b463..f4b431d64 100644 --- a/core/client/src/particlesystem/renderers/c_particle_renderer_sprite_trail.cpp +++ b/core/client/src/particlesystem/renderers/c_particle_renderer_sprite_trail.cpp @@ -58,9 +58,8 @@ void CParticleRendererSpriteTrail::RecordRender(prosper::ICommandBuffer &drawCmd auto *dsScene = scene.GetCameraDescriptorSetGraphics(); auto *dsRenderer = renderer.GetRendererDescriptorSet(); auto &dsRenderSettings = c_game->GetGlobalRenderSettingsDescriptorSet(); - auto *dsLights = renderer.GetLightSourceDescriptorSet(); auto *dsShadows = pragma::CShadowComponent::GetDescriptorSet(); - shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsLights, *dsShadows); + shader->RecordBindScene(bindState.commandBuffer, *layout, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsShadows); shader->RecordDraw(bindState, scene, renderer, *m_particleSystem, m_particleSystem->GetOrientationType(), renderFlags); shader->RecordEndDraw(bindState); } diff --git a/core/client/src/rendering/c_forwardplus.cpp b/core/client/src/rendering/c_forwardplus.cpp index d460806c9..02cf54eff 100644 --- a/core/client/src/rendering/c_forwardplus.cpp +++ b/core/client/src/rendering/c_forwardplus.cpp @@ -87,7 +87,7 @@ pragma::rendering::ForwardPlusInstance::ForwardPlusInstance(CRasterizationRender bool pragma::rendering::ForwardPlusInstance::Initialize(prosper::IPrContext &context, uint32_t width, uint32_t height, prosper::Texture &depthTexture) { - if(pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_LIGHTS.IsValid() == false) + if(pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_RENDERER.IsValid() == false) return false; auto workGroupCount = CalcWorkGroupCount(width, height); m_workGroupCountX = workGroupCount.first; @@ -114,7 +114,7 @@ bool pragma::rendering::ForwardPlusInstance::Initialize(prosper::IPrContext &con m_bufVisLightIndex->SetPermanentlyMapped(true, prosper::IBuffer::MapFlags::ReadBit); m_bufVisLightIndex->SetDebugName("vis_light_index_buf"); - m_rasterizer.GetLightSourceDescriptorSet()->SetBindingStorageBuffer(*m_bufTileVisLightIndex, umath::to_integral(pragma::ShaderGameWorldLightingPass::LightBinding::TileVisLightIndexBuffer)); + m_rasterizer.GetRendererDescriptorSet()->SetBindingStorageBuffer(*m_bufTileVisLightIndex, umath::to_integral(pragma::ShaderGameWorldLightingPass::RendererBinding::TileVisLightIndexBuffer)); auto &descSetCompute = *m_rasterizer.GetLightSourceDescriptorSetCompute(); descSetCompute.SetBindingStorageBuffer(*m_bufTileVisLightIndex, umath::to_integral(pragma::ShaderForwardPLightCulling::LightBinding::TileVisLightIndexBuffer)); diff --git a/core/client/src/rendering/shader_processor.cpp b/core/client/src/rendering/shader_processor.cpp index a15794110..6734d64e8 100644 --- a/core/client/src/rendering/shader_processor.cpp +++ b/core/client/src/rendering/shader_processor.cpp @@ -38,16 +38,14 @@ bool pragma::rendering::ShaderProcessor::RecordBindScene(const pragma::CSceneCom auto *dsScene = view ? scene.GetViewCameraDescriptorSet() : scene.GetCameraDescriptorSetGraphics(); auto *dsRenderer = renderer.GetRendererDescriptorSet(); auto &dsRenderSettings = c_game->GetGlobalRenderSettingsDescriptorSet(); - auto *dsLights = renderer.GetLightSourceDescriptorSet(); auto *dsShadows = pragma::CShadowComponent::GetDescriptorSet(); assert(dsScene); assert(dsRenderer); - assert(dsLights); assert(dsShadows); m_sceneC = &scene; m_rendererC = &renderer; // m_sceneFlags = ShaderGameWorld::SceneFlags::None; - shader.RecordBindScene(*this, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsLights, *dsShadows, m_drawOrigin, m_sceneFlags); + shader.RecordBindScene(*this, scene, renderer, *dsScene, *dsRenderer, dsRenderSettings, *dsShadows, m_drawOrigin, m_sceneFlags); return true; } void pragma::rendering::ShaderProcessor::SetDrawOrigin(const Vector4 &drawOrigin) { m_drawOrigin = drawOrigin; } diff --git a/core/client/src/rendering/shaders/c_shader_forwardp_light_culling.cpp b/core/client/src/rendering/shaders/c_shader_forwardp_light_culling.cpp index 7e160d51a..7b9830766 100644 --- a/core/client/src/rendering/shaders/c_shader_forwardp_light_culling.cpp +++ b/core/client/src/rendering/shaders/c_shader_forwardp_light_culling.cpp @@ -16,8 +16,10 @@ using namespace pragma; extern DLLCLIENT CEngine *c_engine; uint32_t ShaderForwardPLightCulling::TILE_SIZE = 16u; +// Note: We *have* to call this descriptor set "RENDERER" because that's the same used in the scene shader +// and they have to match, otherwise the GLSL parser will not be able to resolve the descriptor set decltype(ShaderForwardPLightCulling::DESCRIPTOR_SET_LIGHTS) ShaderForwardPLightCulling::DESCRIPTOR_SET_LIGHTS = { - "LIGHTS", + "RENDERER", {prosper::DescriptorSetInfo::Binding {"LIGHT_BUFFERS", LIGHT_SOURCE_BUFFER_TYPE, prosper::ShaderStageFlags::ComputeBit}, prosper::DescriptorSetInfo::Binding {"VISIBLE_LIGHT_TILE_INDEX_BUFFER", prosper::DescriptorType::StorageBuffer, prosper::ShaderStageFlags::ComputeBit}, prosper::DescriptorSetInfo::Binding {"SHADOW_BUFFERS", LIGHT_SOURCE_BUFFER_TYPE, prosper::ShaderStageFlags::ComputeBit}, prosper::DescriptorSetInfo::Binding {"VISIBLE_LIGHT_INDEX_BUFFER", prosper::DescriptorType::StorageBuffer, prosper::ShaderStageFlags::ComputeBit}, prosper::DescriptorSetInfo::Binding {"DEPTH_MAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::ComputeBit}}, diff --git a/core/client/src/rendering/shaders/c_shader_lua.cpp b/core/client/src/rendering/shaders/c_shader_lua.cpp index e15c9d9b3..aa9448e2d 100644 --- a/core/client/src/rendering/shaders/c_shader_lua.cpp +++ b/core/client/src/rendering/shaders/c_shader_lua.cpp @@ -294,9 +294,9 @@ pragma::LShaderGameWorldLightingPass::LShaderGameWorldLightingPass() : TLShaderB } pragma::LShaderGameWorldLightingPass::~LShaderGameWorldLightingPass() {} void pragma::LShaderGameWorldLightingPass::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { - ShaderGameWorldLightingPass::RecordBindScene(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows, drawOrigin, inOutSceneFlags); + ShaderGameWorldLightingPass::RecordBindScene(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsShadows, drawOrigin, inOutSceneFlags); RecordPushSceneConstants(shaderProcessor, scene, drawOrigin); if(m_pushConstants->GetSize() > 0) diff --git a/core/client/src/rendering/shaders/c_shader_shadow.cpp b/core/client/src/rendering/shaders/c_shader_shadow.cpp index d459b6df0..b0d1030ae 100644 --- a/core/client/src/rendering/shaders/c_shader_shadow.cpp +++ b/core/client/src/rendering/shaders/c_shader_shadow.cpp @@ -61,7 +61,6 @@ void ShaderShadow::InitializeRenderPass(std::shared_ptr &o } uint32_t ShaderShadow::GetRenderSettingsDescriptorSetIndex() const { return DESCRIPTOR_SET_RENDER_SETTINGS.setIndex; } uint32_t ShaderShadow::GetCameraDescriptorSetIndex() const { return std::numeric_limits::max(); } -uint32_t ShaderShadow::GetLightDescriptorSetIndex() const { return std::numeric_limits::max(); } uint32_t ShaderShadow::GetInstanceDescriptorSetIndex() const { return DESCRIPTOR_SET_INSTANCE.setIndex; } void ShaderShadow::GetVertexAnimationPushConstantInfo(uint32_t &offset) const { offset = offsetof(PushConstants, vertexAnimInfo); } void ShaderShadow::InitializeShaderResources() @@ -101,7 +100,7 @@ void ShaderShadow::InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pi uint32_t ShaderShadow::GetSceneDescriptorSetIndex() const { return DESCRIPTOR_SET_SCENE.setIndex; } void ShaderShadow::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { std::array descSets {&dsScene, &dsRenderSettings}; diff --git a/core/client/src/rendering/shaders/particles/c_shader_particle_2d_base.cpp b/core/client/src/rendering/shaders/particles/c_shader_particle_2d_base.cpp index 1f63493d2..59a68453b 100644 --- a/core/client/src/rendering/shaders/particles/c_shader_particle_2d_base.cpp +++ b/core/client/src/rendering/shaders/particles/c_shader_particle_2d_base.cpp @@ -54,7 +54,6 @@ decltype(ShaderParticle2DBase::DESCRIPTOR_SET_ANIMATION) ShaderParticle2DBase::D decltype(ShaderParticle2DBase::DESCRIPTOR_SET_SCENE) ShaderParticle2DBase::DESCRIPTOR_SET_SCENE = {&ShaderSceneLit::DESCRIPTOR_SET_SCENE}; decltype(ShaderParticle2DBase::DESCRIPTOR_SET_RENDERER) ShaderParticle2DBase::DESCRIPTOR_SET_RENDERER = {&ShaderSceneLit::DESCRIPTOR_SET_RENDERER}; decltype(ShaderParticle2DBase::DESCRIPTOR_SET_RENDER_SETTINGS) ShaderParticle2DBase::DESCRIPTOR_SET_RENDER_SETTINGS = {&ShaderSceneLit::DESCRIPTOR_SET_RENDER_SETTINGS}; -decltype(ShaderParticle2DBase::DESCRIPTOR_SET_LIGHTS) ShaderParticle2DBase::DESCRIPTOR_SET_LIGHTS = {&ShaderSceneLit::DESCRIPTOR_SET_LIGHTS}; decltype(ShaderParticle2DBase::DESCRIPTOR_SET_SHADOWS) ShaderParticle2DBase::DESCRIPTOR_SET_SHADOWS = {&ShaderSceneLit::DESCRIPTOR_SET_SHADOWS}; static uint32_t get_vertex_index(uint32_t absVertIdx) @@ -95,7 +94,6 @@ void ShaderParticle2DBase::RegisterDefaultGfxPipelineDescriptorSetGroups() AddDescriptorSetGroup(DESCRIPTOR_SET_SCENE); AddDescriptorSetGroup(DESCRIPTOR_SET_RENDERER); AddDescriptorSetGroup(DESCRIPTOR_SET_RENDER_SETTINGS); - AddDescriptorSetGroup(DESCRIPTOR_SET_LIGHTS); AddDescriptorSetGroup(DESCRIPTOR_SET_SHADOWS); } @@ -132,7 +130,6 @@ std::optional ShaderParticle2DBase::RecordBeginDraw(prosper::ShaderBin } uint32_t ShaderParticle2DBase::GetRenderSettingsDescriptorSetIndex() const { return DESCRIPTOR_SET_RENDER_SETTINGS.setIndex; } -uint32_t ShaderParticle2DBase::GetLightDescriptorSetIndex() const { return DESCRIPTOR_SET_LIGHTS.setIndex; } uint32_t ShaderParticle2DBase::GetCameraDescriptorSetIndex() const { return DESCRIPTOR_SET_SCENE.setIndex; } std::shared_ptr ShaderParticle2DBase::InitializeMaterialDescriptorSet(CMaterial &mat) @@ -258,9 +255,9 @@ bool ShaderParticle2DBase::RecordParticleMaterial(prosper::ShaderBindState &bind uint32_t ShaderParticle2DBase::GetSceneDescriptorSetIndex() const { return DESCRIPTOR_SET_SCENE.setIndex; } bool ShaderParticle2DBase::RecordBindScene(prosper::ICommandBuffer &cmd, const prosper::IShaderPipelineLayout &layout, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows) const { - std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsLights, &dsShadows}; + std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsShadows}; static const std::vector dynamicOffsets {}; // TODO: Pick correct pipeline index return cmd.RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, layout, GetSceneDescriptorSetIndex(), descSets, dynamicOffsets); diff --git a/core/client/src/rendering/shaders/particles/c_shader_particle_blob.cpp b/core/client/src/rendering/shaders/particles/c_shader_particle_blob.cpp index 22bcdb3b7..f64700673 100644 --- a/core/client/src/rendering/shaders/particles/c_shader_particle_blob.cpp +++ b/core/client/src/rendering/shaders/particles/c_shader_particle_blob.cpp @@ -31,7 +31,6 @@ decltype(ShaderParticleBlob::DESCRIPTOR_SET_PARTICLE_DATA) ShaderParticleBlob::D decltype(ShaderParticleBlob::DESCRIPTOR_SET_SCENE) ShaderParticleBlob::DESCRIPTOR_SET_SCENE = {&ShaderParticle2DBase::DESCRIPTOR_SET_SCENE}; decltype(ShaderParticleBlob::DESCRIPTOR_SET_RENDERER) ShaderParticleBlob::DESCRIPTOR_SET_RENDERER = {&ShaderParticle2DBase::DESCRIPTOR_SET_RENDERER}; decltype(ShaderParticleBlob::DESCRIPTOR_SET_RENDER_SETTINGS) ShaderParticleBlob::DESCRIPTOR_SET_RENDER_SETTINGS = {&ShaderParticle2DBase::DESCRIPTOR_SET_RENDER_SETTINGS}; -decltype(ShaderParticleBlob::DESCRIPTOR_SET_LIGHTS) ShaderParticleBlob::DESCRIPTOR_SET_LIGHTS = {&ShaderParticle2DBase::DESCRIPTOR_SET_LIGHTS}; decltype(ShaderParticleBlob::DESCRIPTOR_SET_SHADOWS) ShaderParticleBlob::DESCRIPTOR_SET_SHADOWS = {&ShaderParticle2DBase::DESCRIPTOR_SET_SHADOWS}; decltype(ShaderParticleBlob::DESCRIPTOR_SET_PBR) ShaderParticleBlob::DESCRIPTOR_SET_PBR = {&ShaderPBR::DESCRIPTOR_SET_PBR}; @@ -101,7 +100,6 @@ void ShaderParticleBlob::InitializeShaderResources() AddDescriptorSetGroup(DESCRIPTOR_SET_SCENE); AddDescriptorSetGroup(DESCRIPTOR_SET_RENDERER); AddDescriptorSetGroup(DESCRIPTOR_SET_RENDER_SETTINGS); - AddDescriptorSetGroup(DESCRIPTOR_SET_LIGHTS); AddDescriptorSetGroup(DESCRIPTOR_SET_SHADOWS); AddDescriptorSetGroup(DESCRIPTOR_SET_PBR); } @@ -118,9 +116,9 @@ void ShaderParticleBlob::InitializeGfxPipeline(prosper::GraphicsPipelineCreateIn } bool ShaderParticleBlob::RecordBindScene(prosper::ICommandBuffer &cmd, const prosper::IShaderPipelineLayout &layout, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows) const { - return ShaderParticle2DBase::RecordBindScene(cmd, layout, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows); + return ShaderParticle2DBase::RecordBindScene(cmd, layout, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsShadows); } bool ShaderParticleBlob::RecordDraw(prosper::ShaderBindState &bindState, pragma::CSceneComponent &scene, const CRasterizationRendererComponent &renderer, const pragma::CParticleSystemComponent &ps, pragma::CParticleSystemComponent::OrientationType orientationType, diff --git a/core/client/src/rendering/shaders/world/c_shader_eye.cpp b/core/client/src/rendering/shaders/world/c_shader_eye.cpp index 0509ee159..c452154bd 100644 --- a/core/client/src/rendering/shaders/world/c_shader_eye.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_eye.cpp @@ -55,7 +55,7 @@ bool ShaderEye::BindEyeball(rendering::ShaderProcessor &shaderProcessor, uint32_ void ShaderEye::InitializeGfxPipelinePushConstantRanges() { AttachPushConstantRange(0u, sizeof(ShaderPBR::PushConstants) + sizeof(PushConstants), prosper::ShaderStageFlags::FragmentBit | prosper::ShaderStageFlags::VertexBit); } void ShaderEye::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { RecordPushSceneConstants(shaderProcessor, scene, drawOrigin); @@ -66,7 +66,7 @@ void ShaderEye::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, con // auto iblStrength = 1.f; - RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows, inOutSceneFlags, iblStrength); + RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsShadows, inOutSceneFlags, iblStrength); } bool ShaderEye::OnRecordDrawMesh(rendering::ShaderProcessor &shaderProcessor, CModelSubMesh &mesh) const { return BindEyeball(shaderProcessor, mesh.GetSkinTextureIndex()); } diff --git a/core/client/src/rendering/shaders/world/c_shader_glow.cpp b/core/client/src/rendering/shaders/world/c_shader_glow.cpp index 3e338901c..ff6a950d2 100644 --- a/core/client/src/rendering/shaders/world/c_shader_glow.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_glow.cpp @@ -201,10 +201,10 @@ void ShaderGlow::InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipe // void ShaderGlow::RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const { outIblStrength = 1.f; - std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsLights, &dsShadows, GetReflectionProbeDescriptorSet(scene, outIblStrength, inOutSceneFlags)}; + std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsShadows, GetReflectionProbeDescriptorSet(scene, outIblStrength, inOutSceneFlags)}; static const std::vector dynamicOffsets {}; shaderProcessor.GetCommandBuffer().RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, shaderProcessor.GetCurrentPipelineLayout(), GetSceneDescriptorSetIndex(), descSets, dynamicOffsets); @@ -224,10 +224,10 @@ prosper::IDescriptorSet *ShaderGlow::GetReflectionProbeDescriptorSet(const pragm } void ShaderGlow::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { auto iblStrength = 1.f; - RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows, inOutSceneFlags, iblStrength); + RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsShadows, inOutSceneFlags, iblStrength); ShaderGameWorldLightingPass::PushConstants pushConstants {}; pushConstants.Initialize(); diff --git a/core/client/src/rendering/shaders/world/c_shader_graph.cpp b/core/client/src/rendering/shaders/world/c_shader_graph.cpp index 2e739f575..c649e1c3f 100644 --- a/core/client/src/rendering/shaders/world/c_shader_graph.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_graph.cpp @@ -103,7 +103,7 @@ void ShaderGraph::OnPipelinesInitialized() { ShaderGameWorldLightingPass::OnPipe void ShaderGraph::InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) { ShaderGameWorldLightingPass::InitializeGfxPipeline(pipelineInfo, pipelineIdx); } void ShaderGraph::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { ShaderGameWorldLightingPass::PushConstants pushConstants {}; pushConstants.Initialize(); diff --git a/core/client/src/rendering/shaders/world/c_shader_pbr.cpp b/core/client/src/rendering/shaders/world/c_shader_pbr.cpp index 51fb8738c..0c727926e 100644 --- a/core/client/src/rendering/shaders/world/c_shader_pbr.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_pbr.cpp @@ -140,10 +140,10 @@ void ShaderPBR::InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipel // void ShaderPBR::RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const { outIblStrength = 1.f; - std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsLights, &dsShadows, GetReflectionProbeDescriptorSet(scene, outIblStrength, inOutSceneFlags)}; + std::array descSets {&dsScene, &dsRenderer, &dsRenderSettings, &dsShadows, GetReflectionProbeDescriptorSet(scene, outIblStrength, inOutSceneFlags)}; static const std::vector dynamicOffsets {}; shaderProcessor.GetCommandBuffer().RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, shaderProcessor.GetCurrentPipelineLayout(), GetSceneDescriptorSetIndex(), descSets, dynamicOffsets); @@ -163,10 +163,10 @@ prosper::IDescriptorSet *ShaderPBR::GetReflectionProbeDescriptorSet(const pragma } void ShaderPBR::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { auto iblStrength = 1.f; - RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsLights, dsShadows, inOutSceneFlags, iblStrength); + RecordBindSceneDescriptorSets(shaderProcessor, scene, renderer, dsScene, dsRenderer, dsRenderSettings, dsShadows, inOutSceneFlags, iblStrength); ShaderGameWorldLightingPass::PushConstants pushConstants {}; pushConstants.Initialize(); diff --git a/core/client/src/rendering/shaders/world/c_shader_prepass.cpp b/core/client/src/rendering/shaders/world/c_shader_prepass.cpp index 87b16b561..92be005a8 100644 --- a/core/client/src/rendering/shaders/world/c_shader_prepass.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_prepass.cpp @@ -128,7 +128,7 @@ void ShaderPrepassBase::GetVertexAnimationPushConstantInfo(uint32_t &offset) con // void ShaderPrepassBase::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { std::array descSets {&dsScene, &dsRenderSettings}; diff --git a/core/client/src/rendering/shaders/world/c_shader_scene.cpp b/core/client/src/rendering/shaders/world/c_shader_scene.cpp index c74547d0c..cb55c326b 100644 --- a/core/client/src/rendering/shaders/world/c_shader_scene.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_scene.cpp @@ -46,6 +46,10 @@ decltype(ShaderScene::DESCRIPTOR_SET_SCENE) ShaderScene::DESCRIPTOR_SET_SCENE = decltype(ShaderScene::DESCRIPTOR_SET_RENDERER) ShaderScene::DESCRIPTOR_SET_RENDERER = { "RENDERER", {prosper::DescriptorSetInfo::Binding {"RENDERER", prosper::DescriptorType::UniformBuffer, prosper::ShaderStageFlags::FragmentBit}, prosper::DescriptorSetInfo::Binding {"SSAO_MAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit}, + prosper::DescriptorSetInfo::Binding {"LIGHT_BUFFERS", LIGHT_SOURCE_BUFFER_TYPE, prosper::ShaderStageFlags::FragmentBit}, + prosper::DescriptorSetInfo::Binding {"VISIBLE_LIGHT_TILE_INDEX_BUFFER", prosper::DescriptorType::StorageBuffer, prosper::ShaderStageFlags::FragmentBit | prosper::ShaderStageFlags::VertexBit}, + prosper::DescriptorSetInfo::Binding {"SHADOW_BUFFERS", LIGHT_SOURCE_BUFFER_TYPE, prosper::ShaderStageFlags::FragmentBit}, + prosper::DescriptorSetInfo::Binding {"CSM_MAPS", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit, umath::to_integral(GameLimits::MaxCSMCascades)}, prosper::DescriptorSetInfo::Binding {"LIGHTMAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit}, prosper::DescriptorSetInfo::Binding {"INDIRECT_LIGHTMAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit}, prosper::DescriptorSetInfo::Binding {"DIRECTIONAL_LIGHTMAP", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit}}, }; @@ -93,13 +97,6 @@ void ShaderScene::InitializeRenderPass(std::shared_ptr &ou ///////////////////// -decltype(ShaderSceneLit::DESCRIPTOR_SET_LIGHTS) ShaderSceneLit::DESCRIPTOR_SET_LIGHTS = { - "LIGHTS", - {prosper::DescriptorSetInfo::Binding {"LIGHT_BUFFERS", LIGHT_SOURCE_BUFFER_TYPE, prosper::ShaderStageFlags::FragmentBit}, - prosper::DescriptorSetInfo::Binding {"VISIBLE_LIGHT_TILE_INDEX_BUFFER", prosper::DescriptorType::StorageBuffer, prosper::ShaderStageFlags::FragmentBit | prosper::ShaderStageFlags::VertexBit}, - prosper::DescriptorSetInfo::Binding {"SHADOW_BUFFERS", LIGHT_SOURCE_BUFFER_TYPE, prosper::ShaderStageFlags::FragmentBit}, - prosper::DescriptorSetInfo::Binding {"CSM_MAPS", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit, umath::to_integral(GameLimits::MaxCSMCascades)}}, -}; decltype(ShaderSceneLit::DESCRIPTOR_SET_SHADOWS) ShaderSceneLit::DESCRIPTOR_SET_SHADOWS = { "SHADOWS", {prosper::DescriptorSetInfo::Binding {"MAPS", prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit, umath::to_integral(GameLimits::MaxActiveShadowMaps)}, diff --git a/core/client/src/rendering/shaders/world/c_shader_skybox.cpp b/core/client/src/rendering/shaders/world/c_shader_skybox.cpp index d2294b2a8..0c75656c0 100644 --- a/core/client/src/rendering/shaders/world/c_shader_skybox.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_skybox.cpp @@ -90,11 +90,10 @@ void ShaderSkybox::InitializeShaderResources() uint32_t ShaderSkybox::GetRenderSettingsDescriptorSetIndex() const { return std::numeric_limits::max(); } uint32_t ShaderSkybox::GetRendererDescriptorSetIndex() const { return DESCRIPTOR_SET_RENDERER.setIndex; } uint32_t ShaderSkybox::GetCameraDescriptorSetIndex() const { return std::numeric_limits::max(); } -uint32_t ShaderSkybox::GetLightDescriptorSetIndex() const { return std::numeric_limits::max(); } uint32_t ShaderSkybox::GetInstanceDescriptorSetIndex() const { return DESCRIPTOR_SET_INSTANCE.setIndex; } void ShaderSkybox::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings, - prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { std::array descSets {&dsScene, &dsRenderer}; diff --git a/core/client/src/rendering/shaders/world/c_shader_textured.cpp b/core/client/src/rendering/shaders/world/c_shader_textured.cpp index 2c04cb3c8..f461ff076 100644 --- a/core/client/src/rendering/shaders/world/c_shader_textured.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_textured.cpp @@ -75,7 +75,6 @@ decltype(ShaderGameWorldLightingPass::DESCRIPTOR_SET_INSTANCE) ShaderGameWorldLi decltype(ShaderGameWorldLightingPass::DESCRIPTOR_SET_SCENE) ShaderGameWorldLightingPass::DESCRIPTOR_SET_SCENE = {&ShaderEntity::DESCRIPTOR_SET_SCENE}; decltype(ShaderGameWorldLightingPass::DESCRIPTOR_SET_RENDERER) ShaderGameWorldLightingPass::DESCRIPTOR_SET_RENDERER = {&ShaderEntity::DESCRIPTOR_SET_RENDERER}; decltype(ShaderGameWorldLightingPass::DESCRIPTOR_SET_RENDER_SETTINGS) ShaderGameWorldLightingPass::DESCRIPTOR_SET_RENDER_SETTINGS = {&ShaderEntity::DESCRIPTOR_SET_RENDER_SETTINGS}; -decltype(ShaderGameWorldLightingPass::DESCRIPTOR_SET_LIGHTS) ShaderGameWorldLightingPass::DESCRIPTOR_SET_LIGHTS = {&ShaderEntity::DESCRIPTOR_SET_LIGHTS}; decltype(ShaderGameWorldLightingPass::DESCRIPTOR_SET_SHADOWS) ShaderGameWorldLightingPass::DESCRIPTOR_SET_SHADOWS = {&ShaderEntity::DESCRIPTOR_SET_SHADOWS}; static std::shared_ptr g_materialSettingsBuffer = nullptr; @@ -241,7 +240,6 @@ void ShaderGameWorldLightingPass::InitializeGfxPipelineDescriptorSets() AddDescriptorSetGroup(DESCRIPTOR_SET_SCENE); AddDescriptorSetGroup(DESCRIPTOR_SET_RENDERER); AddDescriptorSetGroup(DESCRIPTOR_SET_RENDER_SETTINGS); - AddDescriptorSetGroup(DESCRIPTOR_SET_LIGHTS); AddDescriptorSetGroup(DESCRIPTOR_SET_SHADOWS); } std::unique_ptr ShaderGameWorldLightingPass::CreateMaterialDescriptorSetInfo(const pragma::rendering::shader_material::ShaderMaterial &shaderMaterial) @@ -360,7 +358,6 @@ uint32_t ShaderGameWorldLightingPass::GetCameraDescriptorSetIndex() const { retu uint32_t ShaderGameWorldLightingPass::GetRendererDescriptorSetIndex() const { return DESCRIPTOR_SET_RENDERER.setIndex; } uint32_t ShaderGameWorldLightingPass::GetInstanceDescriptorSetIndex() const { return DESCRIPTOR_SET_INSTANCE.setIndex; } uint32_t ShaderGameWorldLightingPass::GetRenderSettingsDescriptorSetIndex() const { return DESCRIPTOR_SET_RENDER_SETTINGS.setIndex; } -uint32_t ShaderGameWorldLightingPass::GetLightDescriptorSetIndex() const { return DESCRIPTOR_SET_LIGHTS.setIndex; } void ShaderGameWorldLightingPass::GetVertexAnimationPushConstantInfo(uint32_t &offset) const { offset = offsetof(PushConstants, vertexAnimInfo); } bool ShaderGameWorldLightingPass::GetRenderBufferTargets(CModelSubMesh &mesh, uint32_t pipelineIdx, std::vector &outBuffers, std::vector &outOffsets, std::optional &outIndexBufferInfo) const { @@ -489,9 +486,9 @@ std::shared_ptr ShaderGameWorldLightingPass::Initi GameShaderSpecializationConstantFlag ShaderGameWorldLightingPass::GetBaseSpecializationFlags() const { return GameShaderSpecializationConstantFlag::None; } void ShaderGameWorldLightingPass::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, - prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const + prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const { - std::array descSets {descSets[1] = &dsScene, descSets[2] = &dsRenderer, descSets[3] = &dsRenderSettings, descSets[4] = &dsLights, descSets[5] = &dsShadows}; + std::array descSets {descSets[1] = &dsScene, descSets[2] = &dsRenderer, descSets[3] = &dsRenderSettings, descSets[5] = &dsShadows}; RecordPushSceneConstants(shaderProcessor, scene, drawOrigin); static const std::vector dynamicOffsets {}; From e38f485898e78e53165be183844c04e86daf9be0 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Tue, 26 Nov 2024 08:28:36 +0100 Subject: [PATCH 27/64] feat(shader_graph): add image texture node --- assets/shaders/modules/image_texture.glsl | 0 build_scripts/scripts/external_libs.py | 2 +- .../pragma/rendering/shader_graph/module.hpp | 7 +- .../shader_graph/modules/image_texture.hpp | 37 ++++++++++ .../shader_graph/nodes/image_texture.hpp | 31 +++++++++ .../src/rendering/shader_graph/module.cpp | 8 ++- .../shader_graph/modules/image_texture.cpp | 67 +++++++++++++++++++ .../shader_graph/nodes/image_texture.cpp | 54 +++++++++++++++ .../shaders/world/c_shader_graph.cpp | 17 +++-- 9 files changed, 214 insertions(+), 9 deletions(-) create mode 100644 assets/shaders/modules/image_texture.glsl create mode 100644 core/client/include/pragma/rendering/shader_graph/modules/image_texture.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/image_texture.hpp create mode 100644 core/client/src/rendering/shader_graph/modules/image_texture.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/image_texture.cpp diff --git a/assets/shaders/modules/image_texture.glsl b/assets/shaders/modules/image_texture.glsl new file mode 100644 index 000000000..e69de29bb diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index d3e5bb4be..e0952fffc 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -32,7 +32,7 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") -get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","30b7e7bbf06b786340e05ee5fde80842dfaee633") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","885dfe49e45fb21ff650f23c1edc342d3675f673") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") diff --git a/core/client/include/pragma/rendering/shader_graph/module.hpp b/core/client/include/pragma/rendering/shader_graph/module.hpp index 1c5b5e059..1f48ace5b 100644 --- a/core/client/include/pragma/rendering/shader_graph/module.hpp +++ b/core/client/include/pragma/rendering/shader_graph/module.hpp @@ -18,6 +18,9 @@ namespace prosper { namespace pragma { class CSceneComponent; class CRasterizationRendererComponent; + namespace shadergraph { + struct GraphNode; + } }; class CModelSubMesh; @@ -30,8 +33,10 @@ namespace pragma::rendering { virtual void InitializeGfxPipelineDescriptorSets() = 0; virtual void UpdateRenderFlags(CModelSubMesh &mesh, ShaderGameWorld::SceneFlags &inOutFlags) {} virtual void RecordBindScene(ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const = 0; + void SetNodes(std::vector &&nodes) { m_nodes = std::move(nodes); } protected: prosper::Shader &m_shader; + std::vector m_nodes; }; class DLLCLIENT ShaderGraphModuleManager { @@ -39,7 +44,7 @@ namespace pragma::rendering { using Factory = std::function(prosper::Shader &shader)>; ShaderGraphModuleManager() {} void RegisterFactory(const std::string &name, const Factory &factory); - std::unique_ptr CreateModule(const std::string &name, prosper::Shader &shader) const; + std::unique_ptr CreateModule(const std::string &name, prosper::Shader &shader, std::vector &&nodes) const; const std::unordered_map &GetFactories() const { return m_factories; } private: std::unordered_map m_factories; diff --git a/core/client/include/pragma/rendering/shader_graph/modules/image_texture.hpp b/core/client/include/pragma/rendering/shader_graph/modules/image_texture.hpp new file mode 100644 index 000000000..c921fd0e7 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/modules/image_texture.hpp @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_MODULES_IMAGE_TEXTURE_HPP__ +#define __PRAGMA_SHADER_GRAPH_MODULES_IMAGE_TEXTURE_HPP__ + +#include "pragma/clientdefinitions.h" +#include "pragma/rendering/shader_graph/module.hpp" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT ImageTextureModule : public pragma::rendering::ShaderGraphModule { + public: + public: + enum class PBRBinding : uint32_t { + IrradianceMap = 0u, + PrefilterMap, + BRDFMap, + + Count + }; + ImageTextureModule(prosper::Shader &shader); + virtual ~ImageTextureModule() override; + virtual void InitializeGfxPipelineDescriptorSets() override; + virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + private: + prosper::DescriptorSetInfo m_descSetInfo; + std::shared_ptr m_dsg; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/image_texture.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/image_texture.hpp new file mode 100644 index 000000000..d71635c1e --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/image_texture.hpp @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_IMAGE_TEXTURE_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_IMAGE_TEXTURE_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT ImageTextureNode : public pragma::shadergraph::Node { + public: + static constexpr const char *IN_FILENAME = "fileName"; + static constexpr const char *IN_VECTOR = "vector"; + + static constexpr const char *OUT_COLOR = "color"; + static constexpr const char *OUT_ALPHA = "alpha"; + + ImageTextureNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + virtual std::string DoEvaluateResourceDeclarations(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/src/rendering/shader_graph/module.cpp b/core/client/src/rendering/shader_graph/module.cpp index 3d6c36e47..45b35fcd0 100644 --- a/core/client/src/rendering/shader_graph/module.cpp +++ b/core/client/src/rendering/shader_graph/module.cpp @@ -11,11 +11,15 @@ using namespace pragma::rendering; void ShaderGraphModuleManager::RegisterFactory(const std::string &name, const Factory &factory) { m_factories[name] = factory; } -std::unique_ptr ShaderGraphModuleManager::CreateModule(const std::string &name, prosper::Shader &shader) const +std::unique_ptr ShaderGraphModuleManager::CreateModule(const std::string &name, prosper::Shader &shader, std::vector &&nodes) const { auto it = m_factories.find(name); if(it == m_factories.end()) return nullptr; auto &factory = it->second; - return factory(shader); + auto module = factory(shader); + if(!module) + return nullptr; + module->SetNodes(std::move(nodes)); + return module; } diff --git a/core/client/src/rendering/shader_graph/modules/image_texture.cpp b/core/client/src/rendering/shader_graph/modules/image_texture.cpp new file mode 100644 index 000000000..ee72bba21 --- /dev/null +++ b/core/client/src/rendering/shader_graph/modules/image_texture.cpp @@ -0,0 +1,67 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/modules/image_texture.hpp" +#include "pragma/rendering/shader_graph/nodes/image_texture.hpp" +#include "pragma/rendering/render_processor.hpp" +#include +#include +#include +#include +#include + +import pragma.shadergraph; + +using namespace pragma::rendering::shader_graph; + +extern DLLCLIENT CEngine *c_engine; +extern DLLCLIENT ClientState *client; +ImageTextureModule::ImageTextureModule(prosper::Shader &shader) : pragma::rendering::ShaderGraphModule {shader} +{ + //Global settings +textures? + /* prosper::PrDescriptorSetBindingFlags::Cubemap */ +} +ImageTextureModule::~ImageTextureModule() {} +void ImageTextureModule::InitializeGfxPipelineDescriptorSets() +{ + // TODO: Move this somewhere else + std::vector bindings; + bindings.reserve(m_nodes.size()); + for(auto *node : m_nodes) { + auto texName = node->GetBaseVarName() + "_tex"; + ustring::to_upper(texName); + prosper::DescriptorSetInfo::Binding binding {pragma::register_global_string(texName), prosper::DescriptorType::CombinedImageSampler, prosper::ShaderStageFlags::FragmentBit, prosper::PrDescriptorSetBindingFlags::None}; + bindings.push_back(binding); + } + m_descSetInfo = { + "TEST", + bindings, + }; + + // + + m_shader.AddDescriptorSetGroup(m_descSetInfo); + + auto &context = c_engine->GetRenderContext(); + auto dsg = context.CreateDescriptorSetGroup(m_descSetInfo); + auto &ds = *dsg->GetDescriptorSet(0); + auto &texManager = static_cast(client->GetMaterialManager()).GetTextureManager(); + uint32_t bindingIdx = 0; + for(auto *node : m_nodes) { + std::string fileName; + node->GetInputValue(pragma::rendering::shader_graph::ImageTextureNode::IN_FILENAME, fileName); + auto tex = texManager.LoadAsset(fileName); + ds.SetBindingTexture(*tex->GetVkTexture(), bindingIdx++); + } + + m_dsg = dsg; +} +void ImageTextureModule::RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const +{ + shaderProcessor.GetCommandBuffer().RecordBindDescriptorSets(prosper::PipelineBindPoint::Graphics, shaderProcessor.GetCurrentPipelineLayout(), m_descSetInfo.setIndex, *m_dsg->GetDescriptorSet()); +} diff --git a/core/client/src/rendering/shader_graph/nodes/image_texture.cpp b/core/client/src/rendering/shader_graph/nodes/image_texture.cpp new file mode 100644 index 000000000..e78490692 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/image_texture.cpp @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/image_texture.hpp" + +using namespace pragma::rendering::shader_graph; + +ImageTextureNode::ImageTextureNode(const std::string_view &type) : Node {type} +{ + AddInput(IN_FILENAME, pragma::shadergraph::SocketType::String, ""); + AddInput(IN_VECTOR, pragma::shadergraph::SocketType::Vector, Vector3 {0.f, 0.f, 0.f}); // TODO: Make input only, don't allow writing manually + + AddOutput(OUT_COLOR, pragma::shadergraph::SocketType::Color); + AddOutput(OUT_ALPHA, pragma::shadergraph::SocketType::Float); + + AddModuleDependency("image_texture"); +} + +std::string ImageTextureNode::DoEvaluateResourceDeclarations(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + auto prefix = gn.GetBaseVarName() + "_"; + std::string texName = prefix + "tex"; + auto upperTexName = texName; + ustring::to_upper(upperTexName); + code << "layout(LAYOUT_ID(TEST, " << upperTexName << ")) uniform sampler2D " << texName << ";\n"; + return code.str(); +} + +std::string ImageTextureNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + std::string uv; + if(gn.IsInputLinked(IN_VECTOR)) + uv = gn.GetInputNameOrValue(IN_VECTOR); + else + uv = "vec3(get_uv_coordinates(), 0.0)"; + + auto prefix = gn.GetBaseVarName() + "_"; + std::string texName = prefix + "tex"; + code << "vec4 " << prefix << "texCol = texture(" << texName << ", " << uv << ".xy);\n"; + + code << gn.GetGlslOutputDeclaration(OUT_COLOR) << " = "; + code << prefix << "texCol.rgb;\n"; + + code << gn.GetGlslOutputDeclaration(OUT_ALPHA) << " = "; + code << prefix << "texCol.a;\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shaders/world/c_shader_graph.cpp b/core/client/src/rendering/shaders/world/c_shader_graph.cpp index c649e1c3f..99092319e 100644 --- a/core/client/src/rendering/shaders/world/c_shader_graph.cpp +++ b/core/client/src/rendering/shaders/world/c_shader_graph.cpp @@ -64,14 +64,21 @@ void ShaderGraph::InitializeShaderResources() auto graphData = graphManager.GetGraph(GetIdentifier()); if(graphData) { auto &graph = graphData->GetGraph(); - std::unordered_set moduleNames; + struct ModuleData { + std::vector nodes; + }; + std::unordered_map moduleData; for(auto &node : graph->GetNodes()) { auto &deps = (*node)->GetModuleDependencies(); - moduleNames.reserve(moduleNames.size() + deps.size()); - moduleNames.insert(deps.begin(), deps.end()); + moduleData.reserve(moduleData.size() + deps.size()); + for(auto &dep : deps) { + auto &modData = moduleData[dep]; + modData.nodes.push_back(node.get()); + } } - for(auto &modName : moduleNames) { - auto mod = graphManager.GetModuleManager().CreateModule(modName, *this); + for(auto &modData : moduleData) { + auto &modName = modData.first; + auto mod = graphManager.GetModuleManager().CreateModule(modName, *this, std::move(modData.second.nodes)); if(mod) m_modules.emplace_back(std::move(mod)); } From 44db04dd8a5588d33d0c12e2536ab2910b4ec47f Mon Sep 17 00:00:00 2001 From: Silverlan Date: Tue, 26 Nov 2024 08:28:51 +0100 Subject: [PATCH 28/64] feat(shader_graph): add mix glsl module --- assets/shaders/modules/mix.glsl | 219 ++++++++++++++++++ .../shader_graph/modules/image_texture.cpp | 1 + 2 files changed, 220 insertions(+) create mode 100644 assets/shaders/modules/mix.glsl diff --git a/assets/shaders/modules/mix.glsl b/assets/shaders/modules/mix.glsl new file mode 100644 index 000000000..7dbe649db --- /dev/null +++ b/assets/shaders/modules/mix.glsl @@ -0,0 +1,219 @@ +#include "/common/color.glsl" + +vec3 mix_color(vec3 col1, vec3 col2, float t) { + return mix(col1, col2, t); +} + +vec3 add_color(vec3 col1, vec3 col2, float t) { + return mix(col1, col1 +col2, t); +} + +vec3 multiply_color(vec3 col1, vec3 col2, float t) { + return mix(col1, col1 *col2, t); +} + +vec3 screen_color(vec3 col1, vec3 col2, float t) { + float tm = 1.0 -t; + vec3 one = vec3(1.0, 1.0, 1.0); + vec3 tm3 = vec3(tm, tm, tm); + + return one -(tm3 +t *(one -col2)) *(one -col1); +} + +vec3 overlay_color(vec3 col1, vec3 col2, float t) { + float tm = 1.0 -t; + + vec3 outcol = col1; + + if(outcol.x < 0.5) + outcol.x *= tm +2.0 *t *col2.x; + else + outcol.x = 1.0 -(tm +2.0 *t *(1.0 -col2.x)) *(1.0 -outcol.x); + + if(outcol.y < 0.5) + outcol.y *= tm +2.0 *t *col2.y; + else + outcol.y = 1.0 -(tm +2.0 *t *(1.0 -col2.y)) *(1.0 -outcol.y); + + if(outcol.z < 0.5) + outcol.z *= tm +2.0 *t *col2.z; + else + outcol.z = 1.0 -(tm +2.0 *t *(1.0 -col2.z)) *(1.0 -outcol.z); + return outcol; +} + +vec3 subtract_color(vec3 col1, vec3 col2, float t) { + return mix(col1, col1 -col2, t); +} + +vec3 divide_color(vec3 col1, vec3 col2, float t) { + float tm = 1.0 -t; + vec3 outcol = col1; + + if(col2.x != 0.0) + outcol.x = tm *outcol.x +t *outcol.x /col2.x; + if(col2.y != 0.0) + outcol.y = tm *outcol.y +t *outcol.y /col2.y; + if(col2.z != 0.0) + outcol.z = tm *outcol.z +t *outcol.z /col2.z; + return outcol; +} + +vec3 difference_color(vec3 col1, vec3 col2, float t) { + return mix(col1, abs(col1 -col2), t); +} + +vec3 darken_color(vec3 col1, vec3 col2, float t) { + return mix(col1, min(col1, col2), t); +} + +vec3 lighten_color(vec3 col1, vec3 col2, float t) { + return mix(col1, max(col1, col2), t); +} + +vec3 dodge_color(vec3 col1, vec3 col2, float t) { + vec3 outcol = col1; + + if(outcol.x != 0.0) { + float tmp = 1.0 -t *col2.x; + if(tmp <= 0.0) + outcol.x = 1.0; + else if((tmp = outcol.x /tmp) > 1.0) + outcol.x = 1.0; + else + outcol.x = tmp; + } + if(outcol.y != 0.0) { + float tmp = 1.0 -t *col2.y; + if(tmp <= 0.0) + outcol.y = 1.0; + else if((tmp = outcol.y /tmp) > 1.0) + outcol.y = 1.0; + else + outcol.y = tmp; + } + if(outcol.z != 0.0) { + float tmp = 1.0 -t *col2.z; + if(tmp <= 0.0) + outcol.z = 1.0; + else if((tmp = outcol.z /tmp) > 1.0) + outcol.z = 1.0; + else + outcol.z = tmp; + } + return outcol; +} + +vec3 burn_color(vec3 col1, vec3 col2, float t) { + float tmp, tm = 1.0 -t; + + vec3 outcol = col1; + + tmp = tm +t *col2.x; + if(tmp <= 0.0) + outcol.x = 0.0; + else if((tmp = (1.0 -(1.0 -outcol.x) /tmp)) < 0.0) + outcol.x = 0.0; + else if(tmp > 1.0) + outcol.x = 1.0; + else + outcol.x = tmp; + + tmp = tm +t *col2.y; + if(tmp <= 0.0) + outcol.y = 0.0; + else if((tmp = (1.0 -(1.0 -outcol.y) /tmp)) < 0.0) + outcol.y = 0.0; + else if(tmp > 1.0) + outcol.y = 1.0; + else + outcol.y = tmp; + + tmp = tm +t *col2.z; + if(tmp <= 0.0) + outcol.z = 0.0; + else if((tmp = (1.0 -(1.0 -outcol.z) /tmp)) < 0.0) + outcol.z = 0.0; + else if(tmp > 1.0) + outcol.z = 1.0; + else + outcol.z = tmp; + return outcol; +} + +vec3 hue_color(vec3 col1, vec3 col2, float t) { + vec3 outcol = col1; + + vec3 hsv2 = rgb_to_hsv(col2); + + if(hsv2.y != 0.0) { + vec3 hsv = rgb_to_hsv(outcol); + hsv.x = hsv2.x; + vec3 tmp = hsv_to_rgb(hsv); + + outcol = mix(outcol, tmp, t); + } + + return outcol; +} + +vec3 saturation_color(vec3 col1, vec3 col2, float t) { + float tm = 1.0 -t; + + vec3 outcol = col1; + + vec3 hsv = rgb_to_hsv(outcol); + + if(hsv.y != 0.0) { + vec3 hsv2 = rgb_to_hsv(col2); + + hsv.y = tm *hsv.y +t *hsv2.y; + outcol = hsv_to_rgb(hsv); + } + + return outcol; +} + +vec3 value_color(vec3 col1, vec3 col2, float t) { + float tm = 1.0 -t; + + vec3 hsv = rgb_to_hsv(col1); + vec3 hsv2 = rgb_to_hsv(col2); + + hsv.z = tm *hsv.z +t *hsv2.z; + + return hsv_to_rgb(hsv); +} + +vec3 color_color(vec3 col1, vec3 col2, float t) { + vec3 outcol = col1; + vec3 hsv2 = rgb_to_hsv(col2); + + if(hsv2.y != 0.0) { + vec3 hsv = rgb_to_hsv(outcol); + hsv.x = hsv2.x; + hsv.y = hsv2.y; + vec3 tmp = hsv_to_rgb(hsv); + + outcol = mix(outcol, tmp, t); + } + + return outcol; +} + +vec3 soft_light_color(vec3 col1, vec3 col2, float t) { + float tm = 1.0 -t; + + vec3 one = make_vec3(1.0, 1.0, 1.0); + vec3 scr = one -(one -col2) *(one -col1); + + return tm *col1 +t *((one -col1) *col2 *col1 +col1 *scr); +} + +vec3 linear_light_color(vec3 col1, vec3 col2, float t) { + return col1 +t *(2.0 *col2 +make_vec3(-1.0, -1.0, -1.0)); +} + +vec3 exclusion_color(vec3 col1, vec3 col2, float t) { + return max(mix(col1, col1 +col2 -2.0 *col1 *col2, t), zero_vec3()); +} diff --git a/core/client/src/rendering/shader_graph/modules/image_texture.cpp b/core/client/src/rendering/shader_graph/modules/image_texture.cpp index ee72bba21..65c4b492c 100644 --- a/core/client/src/rendering/shader_graph/modules/image_texture.cpp +++ b/core/client/src/rendering/shader_graph/modules/image_texture.cpp @@ -21,6 +21,7 @@ using namespace pragma::rendering::shader_graph; extern DLLCLIENT CEngine *c_engine; extern DLLCLIENT ClientState *client; +#pragma optimize("", off) ImageTextureModule::ImageTextureModule(prosper::Shader &shader) : pragma::rendering::ShaderGraphModule {shader} { //Global settings +textures? From aa9aa5a03863232cffef25ae8bb30d5d2081d911 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 27 Nov 2024 11:55:55 +0100 Subject: [PATCH 29/64] feat(shader_graph): add geometry, texture_coordinate and vector_transform nodes --- assets/shaders/modules/entity.glsl | 1 + assets/shaders/modules/uv_data.glsl | 1 + assets/shaders/modules/vertex_data.glsl | 1 + .../rendering/shader_graph/nodes/geometry.hpp | 29 ++++++ .../shader_graph/nodes/texture_coordinate.hpp | 26 +++++ .../shader_graph/nodes/vector_transform.hpp | 43 +++++++++ core/client/src/c_engine.cpp | 15 ++- .../rendering/shader_graph/nodes/camera.cpp | 14 +-- .../src/rendering/shader_graph/nodes/fog.cpp | 8 +- .../rendering/shader_graph/nodes/geometry.cpp | 35 +++++++ .../rendering/shader_graph/nodes/object.cpp | 4 +- .../shader_graph/nodes/texture_coordinate.cpp | 25 +++++ .../src/rendering/shader_graph/nodes/time.cpp | 8 +- .../shader_graph/nodes/vector_transform.cpp | 96 +++++++++++++++++++ 14 files changed, 288 insertions(+), 18 deletions(-) create mode 100644 assets/shaders/modules/entity.glsl create mode 100644 assets/shaders/modules/uv_data.glsl create mode 100644 assets/shaders/modules/vertex_data.glsl create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp create mode 100644 core/client/src/rendering/shader_graph/nodes/geometry.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/vector_transform.cpp diff --git a/assets/shaders/modules/entity.glsl b/assets/shaders/modules/entity.glsl new file mode 100644 index 000000000..266570539 --- /dev/null +++ b/assets/shaders/modules/entity.glsl @@ -0,0 +1 @@ +#include "/common/inputs/entity.glsl" diff --git a/assets/shaders/modules/uv_data.glsl b/assets/shaders/modules/uv_data.glsl new file mode 100644 index 000000000..ab4ed76e1 --- /dev/null +++ b/assets/shaders/modules/uv_data.glsl @@ -0,0 +1 @@ +#include "/common/inputs/textures/parallax_map.glsl" diff --git a/assets/shaders/modules/vertex_data.glsl b/assets/shaders/modules/vertex_data.glsl new file mode 100644 index 000000000..50674c1fa --- /dev/null +++ b/assets/shaders/modules/vertex_data.glsl @@ -0,0 +1 @@ +#include "/common/vertex_outputs/vertex_data.glsl" diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp new file mode 100644 index 000000000..06d57350d --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_GEOMETRY_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_GEOMETRY_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT GeometryNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_POSITION_WS = "position_ws"; + static constexpr const char *OUT_NORMAL_WS = "normal_ws"; + static constexpr const char *OUT_NORMAL_CS = "normal_cs"; + static constexpr const char *OUT_TANGENT_WS = "tangent_ws"; + + GeometryNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp new file mode 100644 index 000000000..c72284aa0 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_TEXTURE_COORDINATE_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_TEXTURE_COORDINATE_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT TextureCoordinateNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_UV = "uv"; + + TextureCoordinateNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp new file mode 100644 index 000000000..b14dc1efa --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_VECTOR_TRANSFORM_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_VECTOR_TRANSFORM_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT VectorTransformNode : public pragma::shadergraph::Node { + public: + enum class Type : uint8_t { + Vector = 0, + Point, + Normal, + }; + + enum class Space : uint8_t { + World = 0, + Object, + Camera, + }; + + static constexpr const char *IN_TRANSFORM_TYPE = "transformType"; + static constexpr const char *IN_CONVERT_FROM = "convertForm"; + static constexpr const char *IN_CONVERT_TO = "convertTo"; + static constexpr const char *IN_VECTOR = "vector"; + + static constexpr const char *OUT_VECTOR = "vector"; + + VectorTransformNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 90b05f34b..99f5e485d 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -112,7 +112,12 @@ static const auto SEPARATE_JOYSTICK_AXES = true; #include "pragma/rendering/shader_graph/nodes/object.hpp" #include "pragma/rendering/shader_graph/nodes/time.hpp" #include "pragma/rendering/shader_graph/nodes/pbr.hpp" +#include "pragma/rendering/shader_graph/nodes/image_texture.hpp" +#include "pragma/rendering/shader_graph/nodes/texture_coordinate.hpp" +#include "pragma/rendering/shader_graph/nodes/vector_transform.hpp" +#include "pragma/rendering/shader_graph/nodes/geometry.hpp" #include "pragma/rendering/shader_graph/modules/pbr.hpp" +#include "pragma/rendering/shader_graph/modules/image_texture.hpp" CEngine::CEngine(int argc, char *argv[]) : Engine(argc, argv), pragma::RenderContext(), m_nearZ(pragma::BaseEnvCameraComponent::DEFAULT_NEAR_Z), //10.0f), //0.1f @@ -197,16 +202,23 @@ CEngine::CEngine(int argc, char *argv[]) { auto regBase = std::make_shared(); regBase->RegisterNode("math"); + regBase->RegisterNode("combine_xyz"); + regBase->RegisterNode("separate_xyz"); + regBase->RegisterNode("vector_math"); + regBase->RegisterNode("mix"); auto regScene = std::make_shared(); regScene->RegisterNode("output"); - regScene->RegisterNode("combine_xyz"); regScene->RegisterNode("camera"); regScene->RegisterNode("fog"); regScene->RegisterNode("lightmap"); regScene->RegisterNode("object"); regScene->RegisterNode("time"); regScene->RegisterNode("pbr"); + regScene->RegisterNode("image_texture"); + regScene->RegisterNode("texture_coordinate"); + regScene->RegisterNode("vector_transform"); + regScene->RegisterNode("geometry"); auto shaderMat = pragma::rendering::shader_material::get_cache().Load("pbr"); auto node = std::make_shared("test", *shaderMat); @@ -222,6 +234,7 @@ CEngine::CEngine(int argc, char *argv[]) m_shaderGraphManager->RegisterGraphTypeManager("object", regScene); m_shaderGraphManager->GetModuleManager().RegisterFactory("pbr", [](prosper::Shader &shader) -> std::unique_ptr { return std::make_unique(shader); }); + m_shaderGraphManager->GetModuleManager().RegisterFactory("image_texture", [](prosper::Shader &shader) -> std::unique_ptr { return std::make_unique(shader); }); } } diff --git a/core/client/src/rendering/shader_graph/nodes/camera.cpp b/core/client/src/rendering/shader_graph/nodes/camera.cpp index dd67beafc..7d545b75d 100644 --- a/core/client/src/rendering/shader_graph/nodes/camera.cpp +++ b/core/client/src/rendering/shader_graph/nodes/camera.cpp @@ -27,12 +27,12 @@ CameraNode::CameraNode(const std::string_view &type) : Node {type} std::string CameraNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_POSITION) << " = u_renderSettings.posCam.xyz;\n"; - code << instance.GetOutputVarName(OUT_FOV) << " = u_renderSettings.posCam.w;\n"; - code << instance.GetOutputVarName(OUT_NEARZ) << " = u_renderSettings.nearZ;\n"; - code << instance.GetOutputVarName(OUT_FARZ) << " = u_renderSettings.farZ;\n"; - code << instance.GetOutputVarName(OUT_VIEW_MATRIX) << " = u_camera.V;\n"; - code << instance.GetOutputVarName(OUT_PROJECTION_MATRIX) << " = u_camera.P;\n"; - code << instance.GetOutputVarName(OUT_VIEW_PROJECTION_MATRIX) << " = u_camera.VP;\n"; + code << instance.GetGlslOutputDeclaration(OUT_POSITION) << " = u_renderSettings.posCam.xyz;\n"; + code << instance.GetGlslOutputDeclaration(OUT_FOV) << " = u_renderSettings.posCam.w;\n"; + code << instance.GetGlslOutputDeclaration(OUT_NEARZ) << " = u_renderSettings.nearZ;\n"; + code << instance.GetGlslOutputDeclaration(OUT_FARZ) << " = u_renderSettings.farZ;\n"; + code << instance.GetGlslOutputDeclaration(OUT_VIEW_MATRIX) << " = u_camera.V;\n"; + code << instance.GetGlslOutputDeclaration(OUT_PROJECTION_MATRIX) << " = u_camera.P;\n"; + code << instance.GetGlslOutputDeclaration(OUT_VIEW_PROJECTION_MATRIX) << " = u_camera.VP;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/fog.cpp b/core/client/src/rendering/shader_graph/nodes/fog.cpp index 868d0f789..9f1004929 100644 --- a/core/client/src/rendering/shader_graph/nodes/fog.cpp +++ b/core/client/src/rendering/shader_graph/nodes/fog.cpp @@ -23,9 +23,9 @@ FogNode::FogNode(const std::string_view &type) : Node {type} std::string FogNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_COLOR) << " = u_fog.color.rgb;\n"; - code << instance.GetOutputVarName(OUT_START_DISTANCE) << " = u_fog.start;\n"; - code << instance.GetOutputVarName(OUT_END_DISTANCE) << " = u_fog.end;\n"; - code << instance.GetOutputVarName(OUT_DENSITY) << " = u_fog.density;\n"; + code << instance.GetGlslOutputDeclaration(OUT_COLOR) << " = u_fog.color.rgb;\n"; + code << instance.GetGlslOutputDeclaration(OUT_START_DISTANCE) << " = u_fog.start;\n"; + code << instance.GetGlslOutputDeclaration(OUT_END_DISTANCE) << " = u_fog.end;\n"; + code << instance.GetGlslOutputDeclaration(OUT_DENSITY) << " = u_fog.density;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/geometry.cpp b/core/client/src/rendering/shader_graph/nodes/geometry.cpp new file mode 100644 index 000000000..2d9790730 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/geometry.cpp @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/geometry.hpp" + +using namespace pragma::rendering::shader_graph; + +GeometryNode::GeometryNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_POSITION_WS, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_NORMAL_WS, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_NORMAL_CS, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_TANGENT_WS, pragma::shadergraph::SocketType::Vector); + + AddModuleDependency("vertex_data"); +} + +std::string GeometryNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + code << gn.GetGlslOutputDeclaration(OUT_POSITION_WS) << " = get_vertex_position_ws();\n"; + code << gn.GetGlslOutputDeclaration(OUT_NORMAL_WS) << " = get_vertex_normal();\n"; + code << gn.GetGlslOutputDeclaration(OUT_NORMAL_CS) << " = get_vertex_normal_cs();\n"; + + auto prefix = gn.GetBaseVarName() + "_"; + std::string tbn = prefix + "tbn"; + code << "mat3 " << tbn << " = get_tbn_matrix();\n"; + code << gn.GetGlslOutputDeclaration(OUT_TANGENT_WS) << " = normalize(" << tbn << "[0]);\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/object.cpp b/core/client/src/rendering/shader_graph/nodes/object.cpp index dc29994c6..87f6e344f 100644 --- a/core/client/src/rendering/shader_graph/nodes/object.cpp +++ b/core/client/src/rendering/shader_graph/nodes/object.cpp @@ -21,7 +21,7 @@ ObjectNode::ObjectNode(const std::string_view &type) : Node {type} std::string ObjectNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_MODEL_MATRIX) << " = u_instance.M;\n"; - code << instance.GetOutputVarName(OUT_COLOR) << " = u_instance.color;\n"; + code << instance.GetGlslOutputDeclaration(OUT_MODEL_MATRIX) << " = u_instance.M;\n"; + code << instance.GetGlslOutputDeclaration(OUT_COLOR) << " = u_instance.color;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp b/core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp new file mode 100644 index 000000000..72a00d1a3 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/texture_coordinate.hpp" + +using namespace pragma::rendering::shader_graph; + +TextureCoordinateNode::TextureCoordinateNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_UV, pragma::shadergraph::SocketType::Vector); + + AddModuleDependency("uv_data"); +} + +std::string TextureCoordinateNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << instance.GetGlslOutputDeclaration(OUT_UV) << " = vec3(get_uv_coordinates(), 0.0);\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/time.cpp b/core/client/src/rendering/shader_graph/nodes/time.cpp index abb08998e..cdf8fb63d 100644 --- a/core/client/src/rendering/shader_graph/nodes/time.cpp +++ b/core/client/src/rendering/shader_graph/nodes/time.cpp @@ -23,9 +23,9 @@ TimeNode::TimeNode(const std::string_view &type) : Node {type} std::string TimeNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_TIME) << " = u_time.time;\n"; - code << instance.GetOutputVarName(OUT_DELTA_TIME) << " = u_time.deltaTime;\n"; - code << instance.GetOutputVarName(OUT_REAL_TIME) << " = u_time.realTime;\n"; - code << instance.GetOutputVarName(OUT_DELTA_REAL_TIME) << " = u_time.deltaRealTime;\n"; + code << instance.GetGlslOutputDeclaration(OUT_TIME) << " = u_time.time;\n"; + code << instance.GetGlslOutputDeclaration(OUT_DELTA_TIME) << " = u_time.deltaTime;\n"; + code << instance.GetGlslOutputDeclaration(OUT_REAL_TIME) << " = u_time.realTime;\n"; + code << instance.GetGlslOutputDeclaration(OUT_DELTA_REAL_TIME) << " = u_time.deltaRealTime;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/vector_transform.cpp b/core/client/src/rendering/shader_graph/nodes/vector_transform.cpp new file mode 100644 index 000000000..98e359c9f --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/vector_transform.cpp @@ -0,0 +1,96 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/vector_transform.hpp" + +using namespace pragma::rendering::shader_graph; + +VectorTransformNode::VectorTransformNode(const std::string_view &type) : Node {type} +{ + AddSocketEnum(IN_TRANSFORM_TYPE, Type::Vector); + AddSocketEnum(IN_CONVERT_FROM, Space::World); + AddSocketEnum(IN_CONVERT_TO, Space::Object); + AddInput(IN_VECTOR, pragma::shadergraph::SocketType::Vector, Vector3 {0.f, 0.f, 0.f}); + AddOutput(OUT_VECTOR, pragma::shadergraph::SocketType::Vector); + + AddModuleDependency("camera"); + AddModuleDependency("entity"); +} + +std::string VectorTransformNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + + auto vector = gn.GetInputNameOrValue(IN_VECTOR); + + auto type = *gn.GetConstantInputValue(IN_TRANSFORM_TYPE); + auto convertFrom = *gn.GetConstantInputValue(IN_CONVERT_FROM); + auto convertTo = *gn.GetConstantInputValue(IN_CONVERT_TO); + + if(convertFrom == convertTo) { + code << gn.GetGlslOutputDeclaration(OUT_VECTOR) << " = " << vector << ";\n"; + return code.str(); + } + + auto prefix = gn.GetBaseVarName() + "_"; + std::string matName = prefix + "mat"; + code << "mat4 " << matName << " = "; + switch(convertFrom) { + case Space::Object: + switch(convertTo) { + case Space::World: + code << "get_model_matrix()"; + break; + case Space::Camera: + code << "get_view_matrix() *get_model_matrix()"; + break; + } + break; + case Space::Camera: + switch(convertTo) { + case Space::World: + code << "inverse(get_view_matrix())"; + break; + case Space::Object: + code << "inverse(get_model_matrix()) *inverse(get_view_matrix())"; + break; + } + break; + case Space::World: + switch(convertTo) { + case Space::Object: + code << "inverse(get_model_matrix())"; + break; + case Space::Camera: + code << "get_view_matrix()"; + break; + } + break; + } + code << ";\n"; + + code << gn.GetGlslOutputDeclaration(OUT_VECTOR) << " = "; + switch(type) { + case Type::Vector: + // Vectors are transformed with the matrix, ignoring translation. + code << "(" << matName << " * vec4(" << vector << ", 0.0)).xyz"; + break; + + case Type::Normal: + // Normals require the inverse transpose of the matrix. + code << "(transpose(inverse(mat3(" << matName << "))) * " << vector << ")"; + break; + + case Type::Point: + // Points are fully transformed, including translation. + code << "(" << matName << " * vec4(" << vector << ", 1.0)).xyz"; + break; + } + code << ";\n"; + return code.str(); +} From 6dc00202fde197260344a8b45ab77ae5d245cb42 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 2 Dec 2024 21:04:13 +0100 Subject: [PATCH 30/64] feat(lua): add math.get_largest_power_of_10 --- core/shared/src/lua/libraries/library.cpp | 50 +++++++++-------------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/core/shared/src/lua/libraries/library.cpp b/core/shared/src/lua/libraries/library.cpp index 4f2f28d60..e8dff71bb 100644 --- a/core/shared/src/lua/libraries/library.cpp +++ b/core/shared/src/lua/libraries/library.cpp @@ -419,7 +419,12 @@ void NetworkState::RegisterSharedLuaLibraries(Lua::Interface &lua) auto modMath = luabind::module_(lua.GetState(), "math"); modMath[luabind::def("approach", umath::approach), luabind::def("get_angle_difference", umath::get_angle_difference), luabind::def("approach_angle", umath::approach_angle), luabind::def("clamp_angle", umath::clamp_angle), luabind::def("is_angle_in_range", umath::is_angle_in_range), luabind::def("clamp", umath::clamp), luabind::def("get_next_power_of_2", umath::next_power_of_2), luabind::def("get_previous_power_of_2", umath::previous_power_of_2), - luabind::def("get_power_of_2_values", umath::get_power_of_2_values), luabind::def("smooth_step", umath::smooth_step), luabind::def("smoother_step", umath::smoother_step), luabind::def("calc_ballistic_range", umath::calc_ballistic_range), + luabind::def("get_power_of_2_values", umath::get_power_of_2_values), luabind::def("get_largest_power_of_10",+[](int32_t n) -> int32_t { + if(n == 0) + return 0; + int exponent = static_cast(std::log10(n)); + return static_cast(std::pow(10, exponent)); + }),luabind::def("smooth_step", umath::smooth_step), luabind::def("smoother_step", umath::smoother_step), luabind::def("calc_ballistic_range", umath::calc_ballistic_range), luabind::def("calc_ballistic_position", umath::calc_ballistic_position), luabind::def("calc_ballistic_angle_of_reach", umath::approach), luabind::def("get_frustum_plane_center", umath::frustum::get_plane_center), luabind::def( "calc_average_rotation", @@ -533,7 +538,7 @@ void NetworkState::RegisterSharedLuaLibraries(Lua::Interface &lua) "remap", +[](float value, float fromLow, float fromHigh, float toLow, float toHigh) { auto diff = fromHigh - fromLow; if(umath::abs(diff) < 0.0001f) - return toLow; + return toLow; return toLow + (value - fromLow) * (toHigh - toLow) / diff; }), luabind::def("is_positive_axis",static_cast(&pragma::is_positive_axis)), @@ -902,19 +907,13 @@ void NetworkState::RegisterSharedLuaLibraries(Lua::Interface &lua) })); classDefCallback.def("Call", static_cast( - [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4}); - })); + [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4}); })); classDefCallback.def("Call", static_cast( - [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5}); - })); + [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5}); })); classDefCallback.def("Call", static_cast( - [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6}); - })); + [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6}); })); classDefCallback.def("Call", static_cast( [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7) { @@ -938,33 +937,25 @@ void NetworkState::RegisterSharedLuaLibraries(Lua::Interface &lua) classDefCallback.def("Call", static_cast( [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, luabind::object arg8, luabind::object arg9, luabind::object arg10, - luabind::object arg11) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11}); - })); + luabind::object arg11) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11}); })); classDefCallback.def("Call", static_cast( [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, luabind::object arg8, luabind::object arg9, luabind::object arg10, - luabind::object arg11, luabind::object arg12) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12}); - })); + luabind::object arg11, luabind::object arg12) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12}); })); classDefCallback.def("Call", static_cast([](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, luabind::object arg8, luabind::object arg9, - luabind::object arg10, luabind::object arg11, luabind::object arg12, luabind::object arg13) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13}); - })); + luabind::object arg10, luabind::object arg11, luabind::object arg12, luabind::object arg13) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13}); })); classDefCallback.def("Call", static_cast([](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, luabind::object arg8, - luabind::object arg9, luabind::object arg10, luabind::object arg11, luabind::object arg12, luabind::object arg13, luabind::object arg14) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14}); - })); + luabind::object, luabind::object)>( + [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, luabind::object arg8, luabind::object arg9, luabind::object arg10, + luabind::object arg11, luabind::object arg12, luabind::object arg13, luabind::object arg14) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14}); })); classDefCallback.def("Call", static_cast([](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, - luabind::object arg8, luabind::object arg9, luabind::object arg10, luabind::object arg11, luabind::object arg12, luabind::object arg13, luabind::object arg14, luabind::object arg15) { - call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15}); - })); + luabind::object, luabind::object, luabind::object)>( + [](lua_State *l, CallbackHandle &cb, luabind::object arg0, luabind::object arg1, luabind::object arg2, luabind::object arg3, luabind::object arg4, luabind::object arg5, luabind::object arg6, luabind::object arg7, luabind::object arg8, luabind::object arg9, luabind::object arg10, + luabind::object arg11, luabind::object arg12, luabind::object arg13, luabind::object arg14, luabind::object arg15) { call_callback(cb, {arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15}); })); classDefCallback.def("IsValid", &Lua_Callback_IsValid); classDefCallback.def("Remove", &Lua_Callback_Remove); @@ -1283,8 +1274,7 @@ static int log(lua_State *l, spdlog::level::level_enum logLevel) template static void add_log_func(lua_State *l, luabind::object &oLogger, const char *name) { - lua_pushcfunction( - l, +[](lua_State *l) -> int { return log(l, TLevel); }); + lua_pushcfunction(l, +[](lua_State *l) -> int { return log(l, TLevel); }); oLogger[name] = luabind::object {luabind::from_stack(l, -1)}; Lua::Pop(l, 1); } From b7bb1570c30e9b785fa4e8ddfdc456e1e9414013 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 2 Dec 2024 21:04:45 +0100 Subject: [PATCH 31/64] feat(lua): update bindings --- core/client/src/lua/classes/c_lwibase.cpp | 91 ++++++++--------------- 1 file changed, 32 insertions(+), 59 deletions(-) diff --git a/core/client/src/lua/classes/c_lwibase.cpp b/core/client/src/lua/classes/c_lwibase.cpp index 2469ba03a..f232d5cd4 100644 --- a/core/client/src/lua/classes/c_lwibase.cpp +++ b/core/client/src/lua/classes/c_lwibase.cpp @@ -230,8 +230,7 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) classDef.def("GetZPos", &::WIBase::GetZPos); classDef.def("HasFocus", &::WIBase::HasFocus); classDef.def("RequestFocus", &::WIBase::RequestFocus); - classDef.def( - "ClearFocus", +[](::WIBase &el) { return WGUI::GetInstance().ClearFocus(el); }); + classDef.def("ClearFocus", +[](::WIBase &el) { return WGUI::GetInstance().ClearFocus(el); }); classDef.def("KillFocus", &::WIBase::KillFocus); classDef.def("KillFocus", &::WIBase::KillFocus, luabind::default_parameter_policy<2, false> {}); classDef.def("TrapFocus", static_cast(&TrapFocus)); @@ -244,10 +243,8 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) classDef.def("SetAutoSizeToContents", static_cast([](lua_State *l, ::WIBase &hPanel) { hPanel.SetAutoSizeToContents(true); })); classDef.def("SetAutoSizeToContents", static_cast([](lua_State *l, ::WIBase &hPanel, bool autoSize) { hPanel.SetAutoSizeToContents(autoSize); })); classDef.def("SetAutoSizeToContents", static_cast([](lua_State *l, ::WIBase &hPanel, bool x, bool y) { hPanel.SetAutoSizeToContents(x, y); })); - classDef.def( - "SetAutoSizeToContents", +[](lua_State *l, ::WIBase &hPanel, bool x, bool y, bool updateImmediately) { hPanel.SetAutoSizeToContents(x, y, updateImmediately); }); - classDef.def( - "UpdateAutoSizeToContents", +[](lua_State *l, ::WIBase &hPanel) { hPanel.UpdateAutoSizeToContents(hPanel.ShouldAutoSizeToContentsX(), hPanel.ShouldAutoSizeToContentsY()); }); + classDef.def("SetAutoSizeToContents", +[](lua_State *l, ::WIBase &hPanel, bool x, bool y, bool updateImmediately) { hPanel.SetAutoSizeToContents(x, y, updateImmediately); }); + classDef.def("UpdateAutoSizeToContents", +[](lua_State *l, ::WIBase &hPanel) { hPanel.UpdateAutoSizeToContents(hPanel.ShouldAutoSizeToContentsX(), hPanel.ShouldAutoSizeToContentsY()); }); classDef.def( "FindAncestorByClass", +[](lua_State *l, ::WIBase &hPanel, std::string className) -> ::WIBase * { ustring::to_lower(className); @@ -314,14 +311,10 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) classDef.def("AnchorWithMargin", static_cast(&::WIBase::AnchorWithMargin)); classDef.def("AnchorWithMargin", static_cast(&::WIBase::AnchorWithMargin)); classDef.def("GetParent", &::WIBase::GetParent); - classDef.def( - "SetParent", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent) { hPanel.SetParent(&hParent); }); - classDef.def( - "SetParent", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent, uint32_t index) { hPanel.SetParent(&hParent, index); }); - classDef.def( - "SetParentAndUpdateWindow", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent) { hPanel.SetParentAndUpdateWindow(&hParent); }); - classDef.def( - "SetParentAndUpdateWindow", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent, uint32_t index) { hPanel.SetParentAndUpdateWindow(&hParent, index); }); + classDef.def("SetParent", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent) { hPanel.SetParent(&hParent); }); + classDef.def("SetParent", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent, uint32_t index) { hPanel.SetParent(&hParent, index); }); + classDef.def("SetParentAndUpdateWindow", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent) { hPanel.SetParentAndUpdateWindow(&hParent); }); + classDef.def("SetParentAndUpdateWindow", +[](lua_State *l, ::WIBase &hPanel, ::WIBase &hParent, uint32_t index) { hPanel.SetParentAndUpdateWindow(&hParent, index); }); classDef.def("ClearParent", &ClearParent); classDef.def("ResetParent", &ResetParent); classDef.def( @@ -346,11 +339,9 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) classDef.def("Draw", static_cast(&Draw)); classDef.def("Draw", static_cast(&Draw)); classDef.def("DrawToTexture", &render_ui); - classDef.def( - "DrawToTexture", +[](::WIBase &el, prosper::RenderTarget &rt) { return render_ui(el, rt, {}); }); + classDef.def("DrawToTexture", +[](::WIBase &el, prosper::RenderTarget &rt) { return render_ui(el, rt, {}); }); classDef.def("DrawToTexture", &draw_to_texture); - classDef.def( - "DrawToTexture", +[](::WIBase &el) { return draw_to_texture(el, {}); }); + classDef.def("DrawToTexture", +[](::WIBase &el) { return draw_to_texture(el, {}); }); classDef.def("RecordDraw", &record_draw_ui); classDef.def("GetX", &GetX); classDef.def("GetY", &GetY); @@ -524,10 +515,8 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) classDef.def("IsRemovalScheduled", &::WIBase::IsRemovalScheduled); classDef.def("GetRootElement", static_cast<::WIBase *(::WIBase::*)()>(&::WIBase::GetRootElement)); classDef.def("GetRootWindow", static_cast(&::WIBase::GetRootWindow)); - classDef.def( - "ClampToBounds", +[](const ::WIBase &el, Vector2i &pos) { el.ClampToBounds(pos); }); - classDef.def( - "ClampToBounds", +[](const ::WIBase &el, Vector2i &pos, Vector2i &size) { el.ClampToBounds(pos, size); }); + classDef.def("ClampToBounds", +[](const ::WIBase &el, Vector2i &pos) { el.ClampToBounds(pos); }); + classDef.def("ClampToBounds", +[](const ::WIBase &el, Vector2i &pos, Vector2i &size) { el.ClampToBounds(pos, size); }); classDef.def( "GetVisibleBounds", +[](const ::WIBase &el) -> std::pair { Vector2i pos, size; @@ -541,12 +530,9 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) el.GetAbsoluteVisibleBounds(pos, size, &absPosParent); return {pos, size, absPosParent}; }); - classDef.def( - "ClampToVisibleBounds", +[](const ::WIBase &el, Vector2i &pos) { el.ClampToVisibleBounds(pos); }); - classDef.def( - "ClampToVisibleBounds", +[](const ::WIBase &el, Vector2i &pos, Vector2i &size) { el.ClampToVisibleBounds(pos, size); }); - classDef.def( - "DebugPrintHierarchy", +[](const ::WIBase &el) { debug_print_hierarchy(el); }); + classDef.def("ClampToVisibleBounds", +[](const ::WIBase &el, Vector2i &pos) { el.ClampToVisibleBounds(pos); }); + classDef.def("ClampToVisibleBounds", +[](const ::WIBase &el, Vector2i &pos, Vector2i &size) { el.ClampToVisibleBounds(pos, size); }); + classDef.def("DebugPrintHierarchy", +[](const ::WIBase &el) { debug_print_hierarchy(el); }); classDef.def("IsFileHovering", &::WIBase::IsFileHovering); classDef.def("SetFileHovering", &::WIBase::SetFileHovering); classDef.def("GetFileDropInputEnabled", &::WIBase::GetFileDropInputEnabled); @@ -563,9 +549,7 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) defDrawInfo.def_readwrite("size", &::WIBase::DrawInfo::size); defDrawInfo.def_readwrite("transform", &::WIBase::DrawInfo::transform); defDrawInfo.def_readwrite("flags", &::WIBase::DrawInfo::flags); - defDrawInfo.property("commandBuffer", static_cast([](lua_State *l, ::WIBase::DrawInfo &drawInfo) -> luabind::object { - return drawInfo.commandBuffer ? luabind::object {l, drawInfo.commandBuffer} : luabind::object {}; - }), + defDrawInfo.property("commandBuffer", static_cast([](lua_State *l, ::WIBase::DrawInfo &drawInfo) -> luabind::object { return drawInfo.commandBuffer ? luabind::object {l, drawInfo.commandBuffer} : luabind::object {}; }), static_cast([](lua_State *l, ::WIBase::DrawInfo &drawInfo, luabind::object o) { if(Lua::IsSet(l, 2) == false) { drawInfo.commandBuffer = nullptr; @@ -580,10 +564,8 @@ void Lua::WIBase::register_class(luabind::class_<::WIBase> &classDef) void Lua::WIButton::register_class(luabind::class_<::WIButton, ::WIBase> &classDef) { - classDef.def( - "SetText", +[](::WIButton &button, const std::string &text) { button.SetText(text); }); - classDef.def( - "GetText", +[](::WIButton &button) { return button.GetText().cpp_str(); }); + classDef.def("SetText", +[](::WIButton &button, const std::string &text) { button.SetText(text); }); + classDef.def("GetText", +[](::WIButton &button) { return button.GetText().cpp_str(); }); } void Lua::WIProgressBar::register_class(luabind::class_<::WIProgressBar, ::WIBase> &classDef) @@ -829,10 +811,8 @@ void Lua::WIDropDownMenu::register_class(luabind::class_<::WIDropDownMenu, luabi classDef.def("SelectOption", static_cast(&::WIDropDownMenu::SelectOption)); classDef.def("SelectOption", static_cast(&::WIDropDownMenu::SelectOption)); classDef.def("ClearOptions", &::WIDropDownMenu::ClearOptions); - classDef.def( - "SelectOptionByText", +[](::WIDropDownMenu &menu, const std::string &text) { return menu.SelectOptionByText(text); }); - classDef.def( - "GetOptionText", +[](::WIDropDownMenu &menu, uint32_t idx) { return menu.GetOptionText(idx).cpp_str(); }); + classDef.def("SelectOptionByText", +[](::WIDropDownMenu &menu, const std::string &text) { return menu.SelectOptionByText(text); }); + classDef.def("GetOptionText", +[](::WIDropDownMenu &menu, uint32_t idx) { return menu.GetOptionText(idx).cpp_str(); }); classDef.def( "FindOptionIndex", +[](::WIDropDownMenu &menu, const std::string &value) -> std::optional { auto n = menu.GetOptionCount(); @@ -847,10 +827,8 @@ void Lua::WIDropDownMenu::register_class(luabind::class_<::WIDropDownMenu, luabi classDef.def("SetOptionText", &::WIDropDownMenu::SetOptionText); classDef.def("SetOptionValue", &::WIDropDownMenu::SetOptionValue); classDef.def("GetValue", &::WIDropDownMenu::GetValue); - classDef.def( - "GetText", +[](const ::WIDropDownMenu &menu) { return menu.GetText().cpp_str(); }); - classDef.def( - "SetText", +[](::WIDropDownMenu &menu, const std::string &text) { return menu.SetText(text); }); + classDef.def("GetText", +[](const ::WIDropDownMenu &menu) { return menu.GetText().cpp_str(); }); + classDef.def("SetText", +[](::WIDropDownMenu &menu, const std::string &text) { return menu.SetText(text); }); classDef.def("GetOptionCount", &::WIDropDownMenu::GetOptionCount); classDef.def("AddOption", static_cast<::WIDropDownMenuOption *(::WIDropDownMenu::*)(const std::string &, const std::string &)>(&::WIDropDownMenu::AddOption)); classDef.def("AddOption", static_cast<::WIDropDownMenuOption *(::WIDropDownMenu::*)(const std::string &)>(&::WIDropDownMenu::AddOption)); @@ -871,8 +849,7 @@ void Lua::WIDropDownMenu::register_class(luabind::class_<::WIDropDownMenu, luabi void Lua::WIText::register_class(luabind::class_<::WIText, ::WIBase> &classDef) { classDef.def("SetText", static_cast([](lua_State *l, ::WIText &hPanel, const std::string &text) { hPanel.SetText(text); })); - classDef.def( - "GetText", +[](const ::WIText &text) { return text.GetText().cpp_str(); }); + classDef.def("GetText", +[](const ::WIText &text) { return text.GetText().cpp_str(); }); classDef.def("GetTextHeight", &::WIText::GetTextHeight); classDef.def("CalcTextSize", &::WIText::CalcTextSize); classDef.def("GetTextWidth", &::WIText::GetTextWidth); @@ -954,19 +931,15 @@ void Lua::WIText::register_class(luabind::class_<::WIText, ::WIBase> &classDef) classDef.def("InsertText", static_cast([](::WIText &hPanel, const std::string &text, util::text::LineIndex lineIdx) { return hPanel.InsertText(text, lineIdx); })); classDef.def("InsertText", static_cast([](::WIText &hPanel, const std::string &text, util::text::LineIndex lineIdx, util::text::CharOffset charOffset) { return hPanel.InsertText(text, lineIdx, charOffset); })); - classDef.def( - "SetMaxLineCount", +[](lua_State *l, ::WIText &hPanel, uint32_t c) { hPanel.GetFormattedTextObject().SetMaxLineCount(c); }); - classDef.def( - "GetMaxLineCount", +[](lua_State *l, ::WIText &hPanel) { return hPanel.GetFormattedTextObject().GetMaxLineCount(); }); - classDef.def( - "AppendText", +[](::WIText &el, const std::string &text) { return el.AppendText(text); }); + classDef.def("SetMaxLineCount", +[](lua_State *l, ::WIText &hPanel, uint32_t c) { hPanel.GetFormattedTextObject().SetMaxLineCount(c); }); + classDef.def("GetMaxLineCount", +[](lua_State *l, ::WIText &hPanel) { return hPanel.GetFormattedTextObject().GetMaxLineCount(); }); + classDef.def("AppendText", +[](::WIText &el, const std::string &text) { return el.AppendText(text); }); classDef.def("AppendLine", static_cast([](lua_State *l, ::WIText &hPanel, const std::string &line) { hPanel.AppendLine(line); })); classDef.def("MoveText", static_cast([](lua_State *l, ::WIText &hPanel, uint32_t lineIdx, uint32_t startOffset, uint32_t len, uint32_t targetLineIdx, uint32_t targetCharOffset) { Lua::PushBool(l, hPanel.MoveText(lineIdx, startOffset, len, targetLineIdx, targetCharOffset)); })); classDef.def("Clear", &::WIText::Clear); - classDef.def( - "Substr", +[](::WIText &el, util::text::TextOffset startOffset, util::text::TextLength len) { return el.Substr(startOffset, len); }); + classDef.def("Substr", +[](::WIText &el, util::text::TextOffset startOffset, util::text::TextLength len) { return el.Substr(startOffset, len); }); classDef.add_static_constant("AUTO_BREAK_NONE", umath::to_integral(::WIText::AutoBreak::NONE)); classDef.add_static_constant("AUTO_BREAK_ANY", umath::to_integral(::WIText::AutoBreak::ANY)); classDef.add_static_constant("AUTO_BREAK_WHITESPACE", umath::to_integral(::WIText::AutoBreak::WHITESPACE)); @@ -974,12 +947,9 @@ void Lua::WIText::register_class(luabind::class_<::WIText, ::WIBase> &classDef) void Lua::WITextEntry::register_class(luabind::class_<::WITextEntry, ::WIBase> &classDef) { - classDef.def( - "SetText", +[](::WITextEntry &el, const std::string &text) { return el.SetText(text); }); - classDef.def( - "GetText", +[](const ::WITextEntry &el) { return el.GetText().cpp_str(); }); - classDef.def( - "GetValue", +[](const ::WITextEntry &el) { return el.GetText().cpp_str(); }); + classDef.def("SetText", +[](::WITextEntry &el, const std::string &text) { return el.SetText(text); }); + classDef.def("GetText", +[](const ::WITextEntry &el) { return el.GetText().cpp_str(); }); + classDef.def("GetValue", +[](const ::WITextEntry &el) { return el.GetText().cpp_str(); }); classDef.def("IsNumeric", &::WITextEntry::IsNumeric); classDef.def("IsEditable", &::WITextEntry::IsEditable); classDef.def("SetEditable", &::WITextEntry::SetEditable); @@ -991,6 +961,9 @@ void Lua::WITextEntry::register_class(luabind::class_<::WITextEntry, ::WIBase> & classDef.def("IsSelectable", &::WITextEntry::IsSelectable); classDef.def("SetSelectable", &::WITextEntry::SetSelectable); classDef.def("GetTextElement", &::WITextEntry::GetTextElement); + + classDef.def("GetCaretPos", &::WITextEntry::GetCaretPos); + classDef.def("SetCaretPos", &::WITextEntry::SetCaretPos); } //////////////////////////////////// From 5d57cce359f26645edf30600d8078d47c2d39ba7 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 2 Dec 2024 21:05:00 +0100 Subject: [PATCH 32/64] feat(shader_graph): update lua bindings --- core/client/src/lua/c_luaclass.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 4c70008be..6e9a3ca85 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -95,6 +95,7 @@ extern DLLCLIENT CGame *c_game; static spdlog::logger &LOGGER_SG = pragma::register_logger("shadergraph"); +#pragma optimize("", off) static void reload_textures(CMaterial &mat) { auto &data = mat.GetDataBlock(); @@ -130,8 +131,18 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma val); } +std::shared_ptr test_shader_graph(); + static void register_shader_graph(lua_State *l, luabind::module_ &modShader) { + modShader[luabind::def("get_test_graph", &test_shader_graph)]; + modShader[luabind::def( + "get_test_node_register", +[]() -> std::shared_ptr { + auto reg = std::make_shared(); + reg->RegisterNode("math"); + return reg; + })]; + auto defGraph = luabind::class_("ShaderGraph"); defGraph.scope[luabind::def( "load", +[](const std::string &type, const std::string &name) -> std::pair, std::optional> { @@ -287,7 +298,7 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader) return Lua::nil; }); }); - defGraphNode.def("CanLink", &pragma::shadergraph::GraphNode::CanLink); + defGraphNode.def("CanLink", static_cast(&pragma::shadergraph::GraphNode::CanLink)); defGraphNode.def( "Link", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &outputName, pragma::shadergraph::GraphNode &linkTarget, const std::string_view &inputName) -> std::pair> { std::string err; From 025d51e6221b2df5d334a458b1880d33dd74a1c0 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 2 Dec 2024 21:05:32 +0100 Subject: [PATCH 33/64] build: update submodules --- build_scripts/build.py | 4 ++-- build_scripts/scripts/external_libs.py | 4 ++-- build_scripts/scripts/modules.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index 5f4e1a71c..7501ca51b 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -842,7 +842,7 @@ def execbuildscript(filepath): ) add_pragma_module( name="pr_prosper_opengl", - commitSha="d73bf6dea11b1a79d5dc4715e224aa4cb15d0d48", + commitSha="9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b", repositoryUrl="https://github.com/Silverlan/pr_prosper_opengl.git" ) add_pragma_module_prebuilt("Silverlan/pr_mount_external_prebuilt") @@ -1136,7 +1136,7 @@ def download_addon(name,addonName,url,commitId=None): curDir = os.getcwd() if not skip_repository_updates: if with_pfm: - download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","f41835d289e2b2da604a3f598590f7ffaaabbf9f") + download_addon("PFM","filmmaker","https://github.com/Silverlan/pfm.git","183eaf445f648b7c055b2ba1f5ff4f7681c3ae36") download_addon("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","a9ea4820f03be250bdf1e6951dad313561b75b17") if with_vr: diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index e0952fffc..31c43aaf6 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -32,9 +32,9 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") -get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","885dfe49e45fb21ff650f23c1edc342d3675f673") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","10f7e88a6c62e265c058bb20381d5e56d1d36ea6") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") -get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") +get_submodule("wgui","https://github.com/Silverlan/wgui.git","edf2c8badee0012274da4ec4a4b2c45223218b90") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") get_submodule("cppbezierfit","https://github.com/Silverlan/cppbezierfit.git","b1f76c0187411230ebe59fa606292b0947e730b6") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 74ec59947..4c4924842 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -11,7 +11,7 @@ get_submodule("interfaces","https://github.com/Silverlan/pragma_interfaces.git","48c1b84f2245324e90871924e4f606f846197818") get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") -get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","d73bf6dea11b1a79d5dc4715e224aa4cb15d0d48") +get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b") get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","b629cd60523450274277cfd353bc78f9aed4c2fa") os.chdir(curDir) From 69b700e92bc394d01022da6812131f7303a8a1e0 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 2 Dec 2024 21:06:02 +0100 Subject: [PATCH 34/64] fix: glsl load error --- assets/shaders/lighting/shadow/fs_shadow_csm.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/shaders/lighting/shadow/fs_shadow_csm.glsl b/assets/shaders/lighting/shadow/fs_shadow_csm.glsl index 8cb449dd4..529356b3e 100644 --- a/assets/shaders/lighting/shadow/fs_shadow_csm.glsl +++ b/assets/shaders/lighting/shadow/fs_shadow_csm.glsl @@ -5,7 +5,7 @@ #include "/common/inputs/csm.glsl" // Required for CSM / PSSM -> standard in shader model 400 and above -//#extension GL_EXT_texture_array : enable +// # extension GL_EXT_texture_array : enable float calculate_csm_shadow(shadowMapSamplerType shadowMap, mat4 vp, vec4 worldCoord, float bias) { From 9471c9080bacef47236470a9c30207b7e116a227 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Mon, 2 Dec 2024 21:06:12 +0100 Subject: [PATCH 35/64] feat(glsl): add compare utility functions --- assets/shaders/math/math.glsl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/assets/shaders/math/math.glsl b/assets/shaders/math/math.glsl index 1db72aaa2..af871756b 100644 --- a/assets/shaders/math/math.glsl +++ b/assets/shaders/math/math.glsl @@ -31,6 +31,9 @@ float length_sqr(vec3 v) { return pow2(v.x) + pow2(v.y) + pow2(v.z); } float units_to_meters(float units) { return units * 0.025; } float meters_to_units(float meters) { return meters / 0.025; } +bool compare(float a, float b) { return abs(a - b) < FLT_EPSILON; } +bool compare(vec3 a, vec3 b) { return compare(a.x, b.x) && compare(a.y, b.y) && compare(a.z, b.z); } + float atan2(in float y, in float x) { // Source: https://stackoverflow.com/a/27228836 From cb2ab7115435f27d35e33665db5f73737f7ecd9a Mon Sep 17 00:00:00 2001 From: Silverlan Date: Tue, 3 Dec 2024 06:31:07 +0100 Subject: [PATCH 36/64] build: update submodule "util_shadergraph" --- build_scripts/scripts/external_libs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 31c43aaf6..016412c42 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -32,7 +32,7 @@ get_submodule("util_versioned_archive","https://github.com/Silverlan/util_versioned_archive.git","e8db74a6ad9ed44d7e8a4492eb8fe44eae3452f6") get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") -get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","10f7e88a6c62e265c058bb20381d5e56d1d36ea6") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","4cfd882fd49632843149750c8f60ce10ba5c3e77") get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") get_submodule("wgui","https://github.com/Silverlan/wgui.git","edf2c8badee0012274da4ec4a4b2c45223218b90") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") From 0a2d520dde60f1cf3233f05173167e70a16a709a Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 4 Dec 2024 19:47:13 +0100 Subject: [PATCH 37/64] feat: remove unnecessary use of swap buffers --- build_scripts/scripts/external_libs.py | 2 +- .../components/c_animated_component.hpp | 12 +++--- .../components/c_render_component.hpp | 14 +++---- .../c_vertex_animated_component.hpp | 6 +-- .../c_rasterization_renderer_component.hpp | 7 ++++ .../entities/environment/c_sky_camera.hpp | 1 + .../pragma/util/c_resource_watcher.hpp | 2 +- .../components/c_animated_component.cpp | 17 ++++---- .../components/c_raytracing_component.cpp | 4 +- .../components/c_render_component.cpp | 39 ++++++++++--------- .../c_vertex_animated_component.cpp | 28 +++++++------ .../c_rasterization_renderer_component.cpp | 7 ++++ .../renderers/rasterization/lighting_pass.cpp | 11 ++++-- .../src/entities/environment/c_sky_camera.cpp | 17 ++++++-- .../component/c_lanimated_component.cpp | 13 ++++--- .../classes/component/c_lrender_component.cpp | 11 ++---- 16 files changed, 111 insertions(+), 80 deletions(-) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 016412c42..da7dcbaca 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","c1eaf0a54f836a5b86b43770f3e37fa1d5e56d9f") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","8610b68c467b5aee3ba97d8f797742b6ba612d5c") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") diff --git a/core/client/include/pragma/entities/components/c_animated_component.hpp b/core/client/include/pragma/entities/components/c_animated_component.hpp index 233c46956..106c20e1d 100644 --- a/core/client/include/pragma/entities/components/c_animated_component.hpp +++ b/core/client/include/pragma/entities/components/c_animated_component.hpp @@ -14,8 +14,8 @@ struct Eyeball; namespace prosper { - class SwapBuffer; - class SwapDescriptorSet; + class IBuffer; + class IDescriptorSetGroup; }; namespace pragma { void initialize_articulated_buffers(); @@ -42,8 +42,6 @@ namespace pragma { bool HasBones() const; using BaseAnimatedComponent::PlayAnimation; - prosper::SwapBuffer *GetSwapBoneBuffer(); - const prosper::SwapBuffer *GetSwapBoneBuffer() const { return const_cast(this)->GetSwapBoneBuffer(); } const prosper::IBuffer *GetBoneBuffer() const; const std::vector &GetBoneMatrices() const; std::vector &GetBoneMatrices(); @@ -65,7 +63,7 @@ namespace pragma { virtual void ResetAnimation(const std::shared_ptr &mdl) override; virtual void GetBaseTypeIndex(std::type_index &outTypeIndex) const override; private: - std::shared_ptr m_boneBuffer = nullptr; + std::shared_ptr m_boneBuffer = nullptr; std::vector m_boneMatrices; StateFlags m_stateFlags = StateFlags::BoneBufferDirty; }; @@ -81,9 +79,9 @@ namespace pragma { }; struct DLLCLIENT CEOnBoneBufferInitialized : public ComponentEvent { - CEOnBoneBufferInitialized(const std::shared_ptr &buffer); + CEOnBoneBufferInitialized(const std::shared_ptr &buffer); virtual void PushArguments(lua_State *l) override; - std::shared_ptr buffer; + std::shared_ptr buffer; }; }; REGISTER_BASIC_BITWISE_OPERATORS(pragma::CAnimatedComponent::StateFlags) diff --git a/core/client/include/pragma/entities/components/c_render_component.hpp b/core/client/include/pragma/entities/components/c_render_component.hpp index de441e93e..362429dc5 100644 --- a/core/client/include/pragma/entities/components/c_render_component.hpp +++ b/core/client/include/pragma/entities/components/c_render_component.hpp @@ -28,8 +28,8 @@ class ModelMesh; namespace prosper { class IUniformResizableBuffer; class IDescriptorSet; - class SwapDescriptorSet; - class SwapBuffer; + class IDescriptorSetGroup; + class IBuffer; }; namespace Intersection { struct LineMeshResult; @@ -76,12 +76,10 @@ namespace pragma { static void RegisterMembers(pragma::EntityComponentManager &componentManager, TRegisterComponentMember registerMember); CRenderComponent(BaseEntity &ent); - const std::shared_ptr &GetSwapRenderBuffer() const; - const prosper::IBuffer &GetRenderBuffer() const; - bool IsRenderBufferValid() const { return m_renderBuffer != nullptr; } + const prosper::IBuffer *GetRenderBuffer() const; std::optional GetRenderBufferIndex() const; + bool IsRenderBufferValid() const { return m_renderBuffer != nullptr; } prosper::IDescriptorSet *GetRenderDescriptorSet() const; - prosper::SwapDescriptorSet *GetSwapRenderDescriptorSet() const; static const std::vector &GetEntitiesExemptFromOcclusionCulling(); static const std::shared_ptr &GetInstanceBuffer(); @@ -257,8 +255,8 @@ namespace pragma { void UpdateAbsoluteSphereRenderBounds(); void UpdateAbsoluteAABBRenderBounds(); pragma::ShaderEntity::InstanceData m_instanceData {}; - std::shared_ptr m_renderBuffer = nullptr; - std::shared_ptr m_renderDescSetGroup = nullptr; + std::shared_ptr m_renderBuffer = nullptr; + std::shared_ptr m_renderDescSetGroup = nullptr; std::optional m_translucencyPassDistanceOverrideSqr {}; }; diff --git a/core/client/include/pragma/entities/components/c_vertex_animated_component.hpp b/core/client/include/pragma/entities/components/c_vertex_animated_component.hpp index 457fc74d6..4168b4c1f 100644 --- a/core/client/include/pragma/entities/components/c_vertex_animated_component.hpp +++ b/core/client/include/pragma/entities/components/c_vertex_animated_component.hpp @@ -13,7 +13,7 @@ namespace prosper { class IDynamicResizableBuffer; - class SwapBuffer; + class IBuffer; }; namespace pragma { DLLCLIENT void initialize_vertex_animation_buffer(); @@ -35,7 +35,7 @@ namespace pragma { virtual void Initialize() override; void UpdateVertexAnimationDataMT(); void UpdateVertexAnimationBuffer(const std::shared_ptr &drawCmd); - const std::shared_ptr &GetVertexAnimationBuffer() const; + const std::shared_ptr &GetVertexAnimationBuffer() const; bool GetVertexAnimationBufferMeshOffset(CModelSubMesh &mesh, uint32_t &offset, uint32_t &animCount) const; bool GetLocalVertexPosition(const ModelSubMesh &subMesh, uint32_t vertexId, Vector3 &pos, Vector3 *optOutNormal = nullptr, float *optOutDelta = nullptr) const; virtual void InitializeLuaObject(lua_State *l) override; @@ -60,7 +60,7 @@ namespace pragma { uint32_t m_maxVertexAnimations = 0u; uint32_t m_activeVertexAnimations = 0u; uint32_t m_vertexAnimationBufferDataCount = 0; - std::shared_ptr m_vertexAnimationBuffer = nullptr; + std::shared_ptr m_vertexAnimationBuffer = nullptr; bool m_bufferUpdateRequired = false; void InitializeVertexAnimationBuffer(); void DestroyVertexAnimationBuffer(); diff --git a/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp b/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp index 29e04cd34..aba9fa992 100644 --- a/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp +++ b/core/client/include/pragma/entities/components/renderers/c_rasterization_renderer_component.hpp @@ -72,6 +72,7 @@ namespace pragma { static ComponentEventId EVENT_POST_PREPASS; static ComponentEventId EVENT_PRE_LIGHTING_PASS; static ComponentEventId EVENT_POST_LIGHTING_PASS; + static ComponentEventId EVENT_UPDATE_RENDER_BUFFERS; static ComponentEventId EVENT_MT_BEGIN_RECORD_SKYBOX; static ComponentEventId EVENT_MT_END_RECORD_SKYBOX; @@ -302,6 +303,12 @@ namespace pragma { pragma::rendering::DepthStageRenderProcessor &renderProcessor; pragma::ShaderPrepassBase &shader; }; + + struct DLLCLIENT CEUpdateRenderBuffers : public ComponentEvent { + CEUpdateRenderBuffers(const util::DrawSceneInfo &drawSceneInfo); + virtual void PushArguments(lua_State *l) override; + const util::DrawSceneInfo &drawSceneInfo; + }; }; REGISTER_BASIC_BITWISE_OPERATORS(pragma::CRasterizationRendererComponent::StateFlags) REGISTER_BASIC_BITWISE_OPERATORS(pragma::RendererData::Flags) diff --git a/core/client/include/pragma/entities/environment/c_sky_camera.hpp b/core/client/include/pragma/entities/environment/c_sky_camera.hpp index fd26eb576..b61af8771 100644 --- a/core/client/include/pragma/entities/environment/c_sky_camera.hpp +++ b/core/client/include/pragma/entities/environment/c_sky_camera.hpp @@ -40,6 +40,7 @@ namespace pragma { CallbackHandle onRendererChanged = {}; CallbackHandle renderSkybox = {}; CallbackHandle renderPrepass = {}; + CallbackHandle updateRenderBuffers = {}; std::shared_ptr renderQueue = nullptr; std::shared_ptr renderQueueTranslucent = nullptr; diff --git a/core/client/include/pragma/util/c_resource_watcher.hpp b/core/client/include/pragma/util/c_resource_watcher.hpp index 2a02cdea3..19f362813 100644 --- a/core/client/include/pragma/util/c_resource_watcher.hpp +++ b/core/client/include/pragma/util/c_resource_watcher.hpp @@ -29,7 +29,7 @@ class DLLCLIENT CResourceWatcherManager : public ResourceWatcherManager { virtual void ReloadTexture(const std::string &path) override; virtual void GetWatchPaths(std::vector &paths) override; public: - using ResourceWatcherManager::ResourceWatcherManager; + CResourceWatcherManager(NetworkState *nw); }; #endif diff --git a/core/client/src/entities/components/c_animated_component.cpp b/core/client/src/entities/components/c_animated_component.cpp index ab2479e8b..6acba757c 100644 --- a/core/client/src/entities/components/c_animated_component.cpp +++ b/core/client/src/entities/components/c_animated_component.cpp @@ -215,13 +215,12 @@ void CAnimatedComponent::ResetAnimation(const std::shared_ptr &mdl) } } -prosper::SwapBuffer *CAnimatedComponent::GetSwapBoneBuffer() { return m_boneBuffer.get(); } -const prosper::IBuffer *CAnimatedComponent::GetBoneBuffer() const { return m_boneBuffer ? &m_boneBuffer->GetBuffer() : nullptr; } +const prosper::IBuffer *CAnimatedComponent::GetBoneBuffer() const { return m_boneBuffer.get(); } void CAnimatedComponent::InitializeBoneBuffer() { if(m_boneBuffer != nullptr) return; - m_boneBuffer = prosper::SwapBuffer::Create(c_engine->GetRenderContext().GetWindow(), *pragma::get_instance_bone_buffer()); + m_boneBuffer = pragma::get_instance_bone_buffer()->AllocateBuffer(); CEOnBoneBufferInitialized evData {m_boneBuffer}; BroadcastEvent(EVENT_ON_BONE_BUFFER_INITIALIZED, evData); @@ -229,8 +228,12 @@ void CAnimatedComponent::InitializeBoneBuffer() void CAnimatedComponent::UpdateBoneBuffer(prosper::IPrimaryCommandBuffer &commandBuffer, bool flagAsDirty) { auto numBones = GetBoneCount(); - if(m_boneBuffer && numBones > 0u && m_boneMatrices.empty() == false) - m_boneBuffer->Update(0ull, GetBoneCount() * sizeof(Mat4), m_boneMatrices.data(), flagAsDirty); + if(m_boneBuffer && flagAsDirty && numBones > 0u && m_boneMatrices.empty() == false) { + constexpr auto pipelineStages = prosper::PipelineStageFlags::FragmentShaderBit | prosper::PipelineStageFlags::VertexShaderBit | prosper::PipelineStageFlags::ComputeShaderBit | prosper::PipelineStageFlags::GeometryShaderBit; + commandBuffer.RecordBufferBarrier(*m_boneBuffer, pipelineStages, prosper::PipelineStageFlags::TransferBit, prosper::AccessFlags::UniformReadBit, prosper::AccessFlags::TransferWriteBit); + commandBuffer.RecordUpdateBuffer(*m_boneBuffer, 0ull, numBones * sizeof(Mat4), m_boneMatrices.data()); + commandBuffer.RecordBufferBarrier(*m_boneBuffer, prosper::PipelineStageFlags::TransferBit, pipelineStages, prosper::AccessFlags::TransferWriteBit, prosper::AccessFlags::UniformReadBit); + } } const std::vector &CAnimatedComponent::GetBoneMatrices() const { return const_cast(this)->GetBoneMatrices(); } std::vector &CAnimatedComponent::GetBoneMatrices() { return m_boneMatrices; } @@ -316,5 +319,5 @@ void CEOnSkeletonUpdated::HandleReturnValues(lua_State *l) ////////////// -CEOnBoneBufferInitialized::CEOnBoneBufferInitialized(const std::shared_ptr &buffer) : buffer {buffer} {} -void CEOnBoneBufferInitialized::PushArguments(lua_State *l) { Lua::Push>(l, buffer); } +CEOnBoneBufferInitialized::CEOnBoneBufferInitialized(const std::shared_ptr &buffer) : buffer {buffer} {} +void CEOnBoneBufferInitialized::PushArguments(lua_State *l) { Lua::Push>(l, buffer); } diff --git a/core/client/src/entities/components/c_raytracing_component.cpp b/core/client/src/entities/components/c_raytracing_component.cpp index fd49a46bd..d57d40e23 100644 --- a/core/client/src/entities/components/c_raytracing_component.cpp +++ b/core/client/src/entities/components/c_raytracing_component.cpp @@ -186,8 +186,8 @@ void CRaytracingComponent::UpdateBuffers(prosper::IPrimaryCommandBuffer &cmd) if(umath::is_flag_set(m_stateFlags, StateFlags::RenderBufferDirty)) { umath::set_flag(m_stateFlags, StateFlags::RenderBufferDirty, false); auto &renderComponent = *whRenderComponent; - auto &wpRenderBuffer = renderComponent.GetRenderBuffer(); - auto index = wpRenderBuffer.GetBaseIndex(); //wpRenderBuffer ? static_cast(wpRenderBuffer->GetBaseIndex()) : prosper::IBuffer::INVALID_SMALL_OFFSET; + auto *renderBuffer = renderComponent.GetRenderBuffer(); + auto index = renderBuffer->GetBaseIndex(); //wpRenderBuffer ? static_cast(wpRenderBuffer->GetBaseIndex()) : prosper::IBuffer::INVALID_SMALL_OFFSET; for(auto &buf : m_subMeshBuffers) cmd.RecordUpdateGenericShaderReadBuffer(*buf, offsetof(SubMeshRenderInfoBufferData, entityBufferIndex), sizeof(index), &index); } diff --git a/core/client/src/entities/components/c_render_component.cpp b/core/client/src/entities/components/c_render_component.cpp index fbac94bdb..de0fa6f25 100644 --- a/core/client/src/entities/components/c_render_component.cpp +++ b/core/client/src/entities/components/c_render_component.cpp @@ -131,11 +131,9 @@ void CRenderComponent::InitializeBuffers() pragma::initialize_articulated_buffers(); pragma::initialize_vertex_animation_buffer(); } -const prosper::IBuffer &CRenderComponent::GetRenderBuffer() const { return m_renderBuffer->GetBuffer(); } -const std::shared_ptr &CRenderComponent::GetSwapRenderBuffer() const { return m_renderBuffer; } -std::optional CRenderComponent::GetRenderBufferIndex() const { return m_renderBuffer ? m_renderBuffer->GetBuffer().GetBaseIndex() : std::optional {}; } -prosper::IDescriptorSet *CRenderComponent::GetRenderDescriptorSet() const { return (m_renderDescSetGroup != nullptr) ? &m_renderDescSetGroup->GetDescriptorSet() : nullptr; } -prosper::SwapDescriptorSet *CRenderComponent::GetSwapRenderDescriptorSet() const { return m_renderDescSetGroup.get(); } +const prosper::IBuffer *CRenderComponent::GetRenderBuffer() const { return m_renderBuffer.get(); } +std::optional CRenderComponent::GetRenderBufferIndex() const { return m_renderBuffer ? m_renderBuffer->GetBaseIndex() : std::optional {}; } +prosper::IDescriptorSet *CRenderComponent::GetRenderDescriptorSet() const { return (m_renderDescSetGroup != nullptr) ? m_renderDescSetGroup->GetDescriptorSet() : nullptr; } void CRenderComponent::ClearRenderObjects() { /*std::unordered_map::iterator it; @@ -680,9 +678,12 @@ void CRenderComponent::UpdateRenderBuffers(const std::shared_ptrUpdate(0ull, sizeof(m_instanceData), &m_instanceData, bufferDirty); + if(bufferDirty) { + constexpr auto pipelineStages = prosper::PipelineStageFlags::FragmentShaderBit | prosper::PipelineStageFlags::VertexShaderBit | prosper::PipelineStageFlags::ComputeShaderBit | prosper::PipelineStageFlags::GeometryShaderBit; + drawCmd->RecordBufferBarrier(*m_renderBuffer, pipelineStages, prosper::PipelineStageFlags::TransferBit, prosper::AccessFlags::UniformReadBit, prosper::AccessFlags::TransferWriteBit); + drawCmd->RecordUpdateBuffer(*m_renderBuffer, 0, m_instanceData); + drawCmd->RecordBufferBarrier(*m_renderBuffer, prosper::PipelineStageFlags::TransferBit, pipelineStages, prosper::AccessFlags::TransferWriteBit, prosper::AccessFlags::UniformReadBit); + } CEOnUpdateRenderBuffers evData {drawCmd}; InvokeEventCallbacks(EVENT_ON_UPDATE_RENDER_BUFFERS, evData); @@ -851,11 +852,13 @@ void CRenderComponent::InitializeRenderBuffers() c_engine->GetRenderContext().WaitIdle(); umath::set_flag(m_stateFlags, StateFlags::RenderBufferDirty); - m_renderBuffer = prosper::SwapBuffer::Create(c_engine->GetRenderContext().GetWindow(), *s_instanceBuffer); - m_renderDescSetGroup = prosper::SwapDescriptorSet::Create(c_engine->GetRenderContext().GetWindow(), pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_INSTANCE); - m_renderDescSetGroup->SetBindingUniformBuffer(*m_renderBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::Instance)); + m_renderBuffer = s_instanceBuffer->AllocateBuffer(); + if(!m_renderBuffer) + return; + m_renderDescSetGroup = c_engine->GetRenderContext().CreateDescriptorSetGroup(pragma::ShaderGameWorldLightingPass::DESCRIPTOR_SET_INSTANCE); + m_renderDescSetGroup->GetDescriptorSet()->SetBindingUniformBuffer(*m_renderBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::Instance)); UpdateBoneBuffer(); - m_renderDescSetGroup->Update(); + m_renderDescSetGroup->GetDescriptorSet()->Update(); UpdateInstantiability(); BroadcastEvent(EVENT_ON_RENDER_BUFFERS_INITIALIZED); @@ -868,12 +871,12 @@ void CRenderComponent::UpdateBoneBuffer() auto pAnimComponent = ent.GetAnimatedComponent(); if(pAnimComponent.expired()) return; - auto wpBoneBuffer = static_cast(*pAnimComponent).GetSwapBoneBuffer(); - if(!wpBoneBuffer) + auto *buf = static_cast(*pAnimComponent).GetBoneBuffer(); + if(!buf) return; c_engine->GetRenderContext().WaitIdle(); - m_renderDescSetGroup->SetBindingUniformBuffer(*wpBoneBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::BoneMatrices)); - m_renderDescSetGroup->Update(); + m_renderDescSetGroup->GetDescriptorSet()->SetBindingUniformBuffer(const_cast(*buf), umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::BoneMatrices)); + m_renderDescSetGroup->GetDescriptorSet()->Update(); } void CRenderComponent::ClearRenderBuffers() { @@ -1092,9 +1095,9 @@ void Console::commands::debug_entity_render_buffer(NetworkState *state, pragma:: Con::cout << "Instance data:" << Con::endl; printInstanceData(instanceData); - auto &buf = renderC->GetRenderBuffer(); + auto *buf = renderC->GetRenderBuffer(); pragma::ShaderEntity::InstanceData bufData; - if(!buf.Read(0, sizeof(bufData), &bufData)) + if(!buf || !buf->Read(0, sizeof(bufData), &bufData)) Con::cwar << "Failed to read buffer data!" << Con::endl; else { if(memcmp(&instanceData, &bufData, sizeof(bufData)) != 0) { diff --git a/core/client/src/entities/components/c_vertex_animated_component.cpp b/core/client/src/entities/components/c_vertex_animated_component.cpp index 5b67627a8..170ab21d1 100644 --- a/core/client/src/entities/components/c_vertex_animated_component.cpp +++ b/core/client/src/entities/components/c_vertex_animated_component.cpp @@ -81,7 +81,7 @@ void CVertexAnimatedComponent::Initialize() GetEntity().AddComponent(); auto whRenderComponent = GetEntity().GetComponent(); - if(whRenderComponent.valid() && whRenderComponent->GetSwapRenderBuffer()) { + if(whRenderComponent.valid() && whRenderComponent->GetRenderBuffer()) { InitializeVertexAnimationBuffer(); whRenderComponent->UpdateInstantiability(); } @@ -94,9 +94,9 @@ void CVertexAnimatedComponent::InitializeVertexAnimationBuffer() auto &ent = GetEntity(); auto whRenderComponent = ent.GetComponent(); auto &mdl = GetEntity().GetModel(); - auto wpRenderBuffer = whRenderComponent.valid() ? whRenderComponent->GetSwapRenderBuffer() : std::weak_ptr {}; - auto *pRenderDescSet = whRenderComponent.valid() ? whRenderComponent->GetSwapRenderDescriptorSet() : nullptr; - if(wpRenderBuffer.expired() == true || mdl == nullptr || pRenderDescSet == nullptr) + auto *buf = whRenderComponent.valid() ? whRenderComponent->GetRenderBuffer() : nullptr; + auto *ds = whRenderComponent.valid() ? whRenderComponent->GetRenderDescriptorSet() : nullptr; + if(!buf || mdl == nullptr || !ds) return; if(m_vertexAnimationBuffer == nullptr) { auto &vertAnimations = mdl->GetVertexAnimations(); @@ -105,7 +105,7 @@ void CVertexAnimatedComponent::InitializeVertexAnimationBuffer() m_maxVertexAnimations += va->GetMeshAnimations().size(); if(m_maxVertexAnimations == 0u) return; - m_vertexAnimationBuffer = prosper::SwapBuffer::Create(c_engine->GetRenderContext().GetWindow(), *globalVertAnimBuffer, sizeof(VertexAnimationData), m_maxVertexAnimations); + m_vertexAnimationBuffer = globalVertAnimBuffer->AllocateBuffer(m_maxVertexAnimations * sizeof(VertexAnimationData)); if(!m_vertexAnimationBuffer) { m_maxVertexAnimations = 0; return; @@ -114,9 +114,9 @@ void CVertexAnimatedComponent::InitializeVertexAnimationBuffer() } auto &vertAnimBuffer = static_cast(*mdl).GetVertexAnimationBuffer(); - pRenderDescSet->SetBindingStorageBuffer(*m_vertexAnimationBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::VertexAnimationFrameData)); - pRenderDescSet->SetBindingStorageBuffer(*vertAnimBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::VertexAnimations)); - pRenderDescSet->Update(); + ds->SetBindingStorageBuffer(*m_vertexAnimationBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::VertexAnimationFrameData)); + ds->SetBindingStorageBuffer(*vertAnimBuffer, umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::VertexAnimations)); + ds->Update(); } void CVertexAnimatedComponent::DestroyVertexAnimationBuffer() @@ -128,14 +128,14 @@ void CVertexAnimatedComponent::DestroyVertexAnimationBuffer() auto &ent = GetEntity(); auto whRenderComponent = ent.GetComponent(); - auto *pRenderDescSet = whRenderComponent.valid() ? whRenderComponent->GetSwapRenderDescriptorSet() : nullptr; + auto *pRenderDescSet = whRenderComponent.valid() ? whRenderComponent->GetRenderDescriptorSet() : nullptr; if(pRenderDescSet) { pRenderDescSet->SetBindingStorageBuffer(*c_engine->GetRenderContext().GetDummyBuffer(), umath::to_integral(pragma::ShaderGameWorldLightingPass::InstanceBinding::VertexAnimationFrameData)); // Reset buffer pRenderDescSet->Update(); } } -const std::shared_ptr &CVertexAnimatedComponent::GetVertexAnimationBuffer() const { return m_vertexAnimationBuffer; } +const std::shared_ptr &CVertexAnimatedComponent::GetVertexAnimationBuffer() const { return m_vertexAnimationBuffer; } void CVertexAnimatedComponent::UpdateVertexAnimationDataMT() { @@ -249,8 +249,12 @@ void CVertexAnimatedComponent::UpdateVertexAnimationBuffer(const std::shared_ptr if(!m_vertexAnimationBuffer) return; auto &buf = *m_vertexAnimationBuffer; - if(m_vertexAnimationBufferDataCount > 0) - buf.Update(0ull, m_vertexAnimationBufferDataCount * sizeof(m_vertexAnimationBufferData.front()), m_vertexAnimationBufferData.data(), m_bufferUpdateRequired); + if(m_vertexAnimationBufferDataCount > 0 && m_bufferUpdateRequired) { + constexpr auto pipelineStages = prosper::PipelineStageFlags::FragmentShaderBit | prosper::PipelineStageFlags::VertexShaderBit | prosper::PipelineStageFlags::ComputeShaderBit | prosper::PipelineStageFlags::GeometryShaderBit; + drawCmd->RecordBufferBarrier(buf, pipelineStages, prosper::PipelineStageFlags::TransferBit, prosper::AccessFlags::ShaderReadBit, prosper::AccessFlags::TransferWriteBit); + drawCmd->RecordUpdateBuffer(buf, 0ull, m_vertexAnimationBufferDataCount * sizeof(m_vertexAnimationBufferData.front()), m_vertexAnimationBufferData.data()); + drawCmd->RecordBufferBarrier(buf, prosper::PipelineStageFlags::TransferBit, pipelineStages, prosper::AccessFlags::TransferWriteBit, prosper::AccessFlags::ShaderWriteBit); + } } bool CVertexAnimatedComponent::GetVertexAnimationBufferMeshOffset(CModelSubMesh &mesh, uint32_t &offset, uint32_t &animCount) const diff --git a/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp b/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp index 7ac642766..bfbc808fa 100644 --- a/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp +++ b/core/client/src/entities/components/renderers/c_rasterization_renderer_component.cpp @@ -46,6 +46,7 @@ ComponentEventId CRasterizationRendererComponent::EVENT_PRE_PREPASS = INVALID_CO ComponentEventId CRasterizationRendererComponent::EVENT_POST_PREPASS = INVALID_COMPONENT_ID; ComponentEventId CRasterizationRendererComponent::EVENT_PRE_LIGHTING_PASS = INVALID_COMPONENT_ID; ComponentEventId CRasterizationRendererComponent::EVENT_POST_LIGHTING_PASS = INVALID_COMPONENT_ID; +ComponentEventId CRasterizationRendererComponent::EVENT_UPDATE_RENDER_BUFFERS = INVALID_COMPONENT_ID; ComponentEventId CRasterizationRendererComponent::EVENT_MT_BEGIN_RECORD_SKYBOX = INVALID_COMPONENT_ID; ComponentEventId CRasterizationRendererComponent::EVENT_MT_END_RECORD_SKYBOX = INVALID_COMPONENT_ID; @@ -72,6 +73,7 @@ void CRasterizationRendererComponent::RegisterEvents(pragma::EntityComponentMana EVENT_POST_PREPASS = registerEvent("POST_PREPASS", ComponentEventInfo::Type::Explicit); EVENT_PRE_LIGHTING_PASS = registerEvent("PRE_LIGHTING_PASS", ComponentEventInfo::Type::Explicit); EVENT_POST_LIGHTING_PASS = registerEvent("POST_LIGHTING_PASS", ComponentEventInfo::Type::Explicit); + EVENT_UPDATE_RENDER_BUFFERS = registerEvent("UPDATE_RENDER_BUFFERS", ComponentEventInfo::Type::Explicit); EVENT_MT_BEGIN_RECORD_SKYBOX = registerEvent("MT_BEGIN_RECORD_SKYBOX", ComponentEventInfo::Type::Explicit); EVENT_MT_END_RECORD_SKYBOX = registerEvent("MT_END_RECORD_SKYBOX", ComponentEventInfo::Type::Explicit); @@ -536,6 +538,11 @@ void CEPrepassStageData::PushArguments(lua_State *l) {} //////// +CEUpdateRenderBuffers::CEUpdateRenderBuffers(const util::DrawSceneInfo &drawSceneInfo) : drawSceneInfo {drawSceneInfo} {} +void CEUpdateRenderBuffers::PushArguments(lua_State *l) {} + +//////// + void CRasterizationRenderer::Initialize() { CBaseEntity::Initialize(); diff --git a/core/client/src/entities/components/renderers/rasterization/lighting_pass.cpp b/core/client/src/entities/components/renderers/rasterization/lighting_pass.cpp index 421ae44a6..6ed732ac1 100644 --- a/core/client/src/entities/components/renderers/rasterization/lighting_pass.cpp +++ b/core/client/src/entities/components/renderers/rasterization/lighting_pass.cpp @@ -132,6 +132,9 @@ void pragma::CRasterizationRendererComponent::UpdatePrepassRenderBuffers(const u CSceneComponent::UpdateRenderBuffers(drawCmd, *sceneRenderDesc.GetRenderQueue(pragma::rendering::SceneRenderPass::View, true /* translucent */), drawSceneInfo.renderStats ? &drawSceneInfo.renderStats->GetPassStats(RenderStats::RenderPass::Prepass) : nullptr); } + CEUpdateRenderBuffers evData {drawSceneInfo}; + InvokeEventCallbacks(EVENT_UPDATE_RENDER_BUFFERS, evData); + c_game->CallLuaCallbacks("UpdateRenderBuffers", &drawSceneInfo); // } @@ -316,7 +319,7 @@ void pragma::CRasterizationRendererComponent::RecordLightingPass(const util::Dra InvokeEventCallbacks(EVENT_MT_END_RECORD_SKYBOX, evDataLightingStage); c_game->StopGPUProfilingStage(); // Skybox - c_game->StopProfilingStage(); // Skybox + c_game->StopProfilingStage(); // Skybox } // Render static world geometry @@ -352,7 +355,7 @@ void pragma::CRasterizationRendererComponent::RecordLightingPass(const util::Dra InvokeEventCallbacks(EVENT_MT_END_RECORD_WORLD, evDataLightingStage); c_game->StopGPUProfilingStage(); // World - c_game->StopProfilingStage(); // World + c_game->StopProfilingStage(); // World } #if DEBUG_RENDER_PERFORMANCE_TEST_ENABLED == 1 } @@ -518,7 +521,7 @@ void pragma::CRasterizationRendererComponent::RecordLightingPass(const util::Dra InvokeEventCallbacks(EVENT_MT_END_RECORD_DEBUG, evDataLightingStage); c_game->StopGPUProfilingStage(); // Debug - c_game->StopProfilingStage(); // Debug + c_game->StopProfilingStage(); // Debug } if((drawSceneInfo.renderFlags & RenderFlags::View) != RenderFlags::None) { @@ -545,7 +548,7 @@ void pragma::CRasterizationRendererComponent::RecordLightingPass(const util::Dra InvokeEventCallbacks(EVENT_MT_END_RECORD_VIEW, evDataLightingStage); c_game->StopGPUProfilingStage(); // View - c_game->StopProfilingStage(); // View + c_game->StopProfilingStage(); // View } c_game->StopProfilingStage(); // RecordLightingPass }); diff --git a/core/client/src/entities/environment/c_sky_camera.cpp b/core/client/src/entities/environment/c_sky_camera.cpp index 15c879307..fb78176df 100644 --- a/core/client/src/entities/environment/c_sky_camera.cpp +++ b/core/client/src/entities/environment/c_sky_camera.cpp @@ -44,6 +44,8 @@ CSkyCameraComponent::SceneData::~SceneData() onBuildRenderQueue.Remove(); if(renderSkybox.IsValid()) renderSkybox.Remove(); + if(updateRenderBuffers.IsValid()) + updateRenderBuffers.Remove(); if(renderPrepass.IsValid()) renderPrepass.Remove(); } @@ -200,6 +202,17 @@ void CSkyCameraComponent::UpdateScenes() UnbindFromShader(rsys); return util::EventReply::Unhandled; }); + sceneData->updateRenderBuffers = rasterizationC->AddEventCallback(pragma::CRasterizationRendererComponent::EVENT_UPDATE_RENDER_BUFFERS, [this, pSceneData, &ent, scene](std::reference_wrapper evData) -> util::EventReply { + auto &updateRenderBuffersInfo = static_cast(evData.get()); + auto &drawSceneInfo = updateRenderBuffersInfo.drawSceneInfo; + auto &drawCmd = drawSceneInfo.commandBuffer; + if(!umath::is_flag_set(drawSceneInfo.renderFlags, RenderFlags::Skybox) || !ent.IsInScene(*scene)) + return util::EventReply::Unhandled; + // Need to update the render buffers for our render queues + CSceneComponent::UpdateRenderBuffers(drawCmd, *pSceneData->renderQueue, drawSceneInfo.renderStats ? &drawSceneInfo.renderStats->GetPassStats(RenderStats::RenderPass::Prepass) : nullptr); + CSceneComponent::UpdateRenderBuffers(drawCmd, *pSceneData->renderQueueTranslucent, drawSceneInfo.renderStats ? &drawSceneInfo.renderStats->GetPassStats(RenderStats::RenderPass::Prepass) : nullptr); + return util::EventReply::Unhandled; + }); sceneData->renderPrepass = rasterizationC->AddEventCallback(pragma::CRasterizationRendererComponent::EVENT_MT_BEGIN_RECORD_PREPASS, [this, pSceneData, &ent, scene](std::reference_wrapper evData) -> util::EventReply { auto &stageData = static_cast(evData.get()); auto &rsys = stageData.renderProcessor; @@ -208,10 +221,6 @@ void CSkyCameraComponent::UpdateScenes() auto &drawCmd = drawSceneInfo.commandBuffer; if(!umath::is_flag_set(drawSceneInfo.renderFlags, RenderFlags::Skybox) || !ent.IsInScene(*scene)) return util::EventReply::Unhandled; - // Need to update the render buffers for our render queues - CSceneComponent::UpdateRenderBuffers(drawCmd, *pSceneData->renderQueue, drawSceneInfo.renderStats ? &drawSceneInfo.renderStats->GetPassStats(RenderStats::RenderPass::Prepass) : nullptr); - CSceneComponent::UpdateRenderBuffers(drawCmd, *pSceneData->renderQueueTranslucent, drawSceneInfo.renderStats ? &drawSceneInfo.renderStats->GetPassStats(RenderStats::RenderPass::Prepass) : nullptr); - rsys.UnbindShader(); BindToShader(rsys); rsys.BindShader(stageData.shader, umath::to_integral(pragma::ShaderPrepass::Pipeline::Opaque)); diff --git a/core/client/src/lua/classes/component/c_lanimated_component.cpp b/core/client/src/lua/classes/component/c_lanimated_component.cpp index 1b8d11ed5..46fb72b2e 100644 --- a/core/client/src/lua/classes/component/c_lanimated_component.cpp +++ b/core/client/src/lua/classes/component/c_lanimated_component.cpp @@ -22,12 +22,13 @@ void Lua::Animated::register_class(lua_State *l, luabind::module_ &entsMod) { auto defCAnimated = pragma::lua::create_entity_component_class("AnimatedComponent"); - defCAnimated.def("GetBoneBuffer", static_cast> (*)(lua_State *, pragma::CAnimatedComponent &)>([](lua_State *l, pragma::CAnimatedComponent &hAnim) -> std::optional> { - auto buf = hAnim.GetSwapBoneBuffer(); - if(!buf) - return {}; - return buf->shared_from_this(); - })); + defCAnimated.def( + "GetBoneBuffer", +[](lua_State *l, pragma::CAnimatedComponent &hAnim) -> std::optional> { + auto *buf = hAnim.GetBoneBuffer(); + if(!buf) + return {}; + return const_cast(buf)->shared_from_this(); + }); defCAnimated.def("GetBoneRenderMatrices", static_cast &(pragma::CAnimatedComponent::*)() const>(&pragma::CAnimatedComponent::GetBoneMatrices)); defCAnimated.def("GetBoneRenderMatrix", static_cast (*)(lua_State *, pragma::CAnimatedComponent &, uint32_t)>([](lua_State *l, pragma::CAnimatedComponent &hAnim, uint32_t boneIndex) -> std::optional { auto &mats = hAnim.GetBoneMatrices(); diff --git a/core/client/src/lua/classes/component/c_lrender_component.cpp b/core/client/src/lua/classes/component/c_lrender_component.cpp index 14bce58fa..c7be22f2f 100644 --- a/core/client/src/lua/classes/component/c_lrender_component.cpp +++ b/core/client/src/lua/classes/component/c_lrender_component.cpp @@ -235,13 +235,10 @@ void Lua::Render::SetLocalRenderBounds(lua_State *l, pragma::CRenderComponent &h void Lua::Render::UpdateRenderBuffers(lua_State *l,pragma::CRenderComponent &hEnt,std::shared_ptr &drawCmd,CSceneHandle &hScene,CCameraHandle &hCam) {UpdateRenderBuffers(l,hEnt,drawCmd,hScene,hCam,false);}*/ void Lua::Render::GetRenderBuffer(lua_State *l, pragma::CRenderComponent &hEnt) { - - if(hEnt.GetSwapRenderBuffer() == nullptr) + auto *buf = hEnt.GetRenderBuffer(); + if(buf == nullptr) return; - auto &buf = hEnt.GetRenderBuffer(); - //if(buf == nullptr) - // return; - Lua::Push(l, buf.shared_from_this()); + Lua::Push(l, buf->shared_from_this()); } void Lua::Render::GetBoneBuffer(lua_State *l, pragma::CRenderComponent &hEnt) { @@ -249,7 +246,7 @@ void Lua::Render::GetBoneBuffer(lua_State *l, pragma::CRenderComponent &hEnt) auto *pAnimComponent = static_cast(hEnt.GetEntity().GetAnimatedComponent().get()); if(pAnimComponent == nullptr) return; - auto buf = pAnimComponent->GetSwapBoneBuffer(); + auto *buf = pAnimComponent->GetBoneBuffer(); if(!buf) return; Lua::Push(l, buf->shared_from_this()); From dbc90e21f42b9ca677714cb2b650e2e648e096e5 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 4 Dec 2024 19:48:20 +0100 Subject: [PATCH 38/64] fix: remove test function --- core/client/src/lua/c_luaclass.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 6e9a3ca85..61298fcae 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -131,11 +131,8 @@ static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma val); } -std::shared_ptr test_shader_graph(); - static void register_shader_graph(lua_State *l, luabind::module_ &modShader) { - modShader[luabind::def("get_test_graph", &test_shader_graph)]; modShader[luabind::def( "get_test_node_register", +[]() -> std::shared_ptr { auto reg = std::make_shared(); From e0b0d2e715a9098909d0367d77e23306d2d381ff Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 4 Dec 2024 19:49:07 +0100 Subject: [PATCH 39/64] feat: improve logging for debug_texture_mipmaps --- core/client/src/debug/c_debug_texture_mipmaps.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/client/src/debug/c_debug_texture_mipmaps.cpp b/core/client/src/debug/c_debug_texture_mipmaps.cpp index 6ae2a6287..38073db03 100644 --- a/core/client/src/debug/c_debug_texture_mipmaps.cpp +++ b/core/client/src/debug/c_debug_texture_mipmaps.cpp @@ -86,9 +86,13 @@ void Console::commands::debug_texture_mipmaps(NetworkState *, pragma::BasePlayer else { auto *asset = materialManager.FindCachedAsset(texPath); auto mat = asset ? msys::CMaterialManager::GetAssetObject(*asset) : nullptr; - auto *diffuseMap = (mat != nullptr) ? mat->GetDiffuseMap() : nullptr; + if(!mat) { + Con::cwar << "No material with name '" << texPath << "' found or loaded!" << Con::endl; + return; + } + auto *diffuseMap = mat->GetDiffuseMap(); if(diffuseMap == nullptr || diffuseMap->texture == nullptr || static_cast(diffuseMap->texture.get())->HasValidVkTexture() == false) { - Con::cwar << "No texture or material with name '" << texPath << "' found or loaded!" << Con::endl; + Con::cwar << "Material '" << texPath << "' has no valid albedo map!" << Con::endl; return; } texture = std::static_pointer_cast(diffuseMap->texture); From 981535d373f051cb3c802376647fc6b875e38dc1 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 4 Dec 2024 19:49:34 +0100 Subject: [PATCH 40/64] fix: imported materials being moved to the wrong location in some cases --- core/client/src/c_engine.cpp | 2 +- core/shared/src/engine.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 99f5e485d..5485a5190 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -903,7 +903,7 @@ bool CEngine::Initialize(int argc, char *argv[]) // Initialize Client Instance auto matManager = msys::CMaterialManager::Create(GetRenderContext()); - matManager->SetImportDirectory("addons/converted/materials"); + matManager->SetImportDirectory("addons/converted/"); InitializeAssetManager(*matManager); pragma::asset::update_extension_cache(pragma::asset::Type::Material); diff --git a/core/shared/src/engine.cpp b/core/shared/src/engine.cpp index b363c0409..ffc5df81c 100644 --- a/core/shared/src/engine.cpp +++ b/core/shared/src/engine.cpp @@ -660,7 +660,7 @@ bool Engine::Initialize(int argc, char *argv[]) // Initialize Server Instance auto matManager = msys::MaterialManager::Create(); - matManager->SetImportDirectory("addons/converted/materials"); + matManager->SetImportDirectory("addons/converted/"); InitializeAssetManager(*matManager); pragma::asset::update_extension_cache(pragma::asset::Type::Map); From d8b24b314ed5a191d6cd91e64d3cfe7909981af4 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Thu, 5 Dec 2024 06:37:23 +0100 Subject: [PATCH 41/64] feat: add option to register custom type handler with resource watcher --- core/client/src/util/c_resource_watcher.cpp | 3 +++ core/shared/include/pragma/util/resource_watcher.h | 3 +++ core/shared/src/util/resource_watcher.cpp | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/core/client/src/util/c_resource_watcher.cpp b/core/client/src/util/c_resource_watcher.cpp index a358282a0..e4d37b4cd 100644 --- a/core/client/src/util/c_resource_watcher.cpp +++ b/core/client/src/util/c_resource_watcher.cpp @@ -27,6 +27,9 @@ decltype(ECResourceWatcherCallbackType::Shader) ECResourceWatcherCallbackType::S decltype(ECResourceWatcherCallbackType::ParticleSystem) ECResourceWatcherCallbackType::ParticleSystem = ECResourceWatcherCallbackType {umath::to_integral(E::ParticleSystem)}; decltype(ECResourceWatcherCallbackType::Count) ECResourceWatcherCallbackType::Count = ECResourceWatcherCallbackType {umath::to_integral(E::Count)}; static auto cvMatStreaming = GetClientConVar("cl_material_streaming_enabled"); + +CResourceWatcherManager::CResourceWatcherManager(NetworkState *nw) : ResourceWatcherManager(nw) {} + void CResourceWatcherManager::ReloadTexture(const std::string &path) { auto *nw = m_networkState; diff --git a/core/shared/include/pragma/util/resource_watcher.h b/core/shared/include/pragma/util/resource_watcher.h index 2e5a4a7de..03dcf1c31 100644 --- a/core/shared/include/pragma/util/resource_watcher.h +++ b/core/shared/include/pragma/util/resource_watcher.h @@ -36,6 +36,7 @@ class Model; class LuaDirectoryWatcherManager; class DLLNETWORK ResourceWatcherManager { public: + using TypeHandler = std::function; ResourceWatcherManager(NetworkState *nw); bool MountDirectory(const std::string &path, bool bAbsolutePath = false); void Poll(); @@ -48,6 +49,7 @@ class DLLNETWORK ResourceWatcherManager { util::ScopeGuard ScopeLock(); bool IsLocked() const; CallbackHandle AddChangeCallback(EResourceWatcherCallbackType type, const std::function, std::reference_wrapper)> &fcallback); + void RegisterTypeHandler(const std::string &ext, const TypeHandler &handler); protected: NetworkState *m_networkState = nullptr; uint32_t m_lockedCount = 0; @@ -63,6 +65,7 @@ class DLLNETWORK ResourceWatcherManager { std::unordered_map> m_callbacks; std::unordered_map> m_watchFiles; std::vector> m_watchers; + std::unordered_map m_typeHandlers; }; #endif diff --git a/core/shared/src/util/resource_watcher.cpp b/core/shared/src/util/resource_watcher.cpp index 04be51c94..eab45bb21 100644 --- a/core/shared/src/util/resource_watcher.cpp +++ b/core/shared/src/util/resource_watcher.cpp @@ -60,6 +60,8 @@ util::ScopeGuard ResourceWatcherManager::ScopeLock() bool ResourceWatcherManager::IsLocked() const { return m_lockedCount > 0; } +void ResourceWatcherManager::RegisterTypeHandler(const std::string &ext, const TypeHandler &handler) { m_typeHandlers[ext] = handler; } + void ResourceWatcherManager::ReloadMaterial(const std::string &path) { auto *nw = m_networkState; @@ -140,6 +142,11 @@ void ResourceWatcherManager::OnResourceChanged(const util::Path &rootPath, const auto &strPath = path.GetString(); auto *nw = m_networkState; auto *game = nw->GetGameState(); + auto it = m_typeHandlers.find(ext); + if(it != m_typeHandlers.end()) { + it->second(path, ext); + return; + } auto assetType = pragma::asset::determine_type_from_extension(ext); if(assetType.has_value()) { if(*assetType == pragma::asset::Type::Model) { From a6cb28cdf93afb8fa78dcd68da973fe2b1fa2e2f Mon Sep 17 00:00:00 2001 From: Silverlan Date: Thu, 5 Dec 2024 21:41:02 +0100 Subject: [PATCH 42/64] fix: vk_dump_* console commands not working --- core/client/src/console/c_cvar_global.cpp | 30 ++++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/core/client/src/console/c_cvar_global.cpp b/core/client/src/console/c_cvar_global.cpp index bd5afead4..a237085ec 100644 --- a/core/client/src/console/c_cvar_global.cpp +++ b/core/client/src/console/c_cvar_global.cpp @@ -597,29 +597,47 @@ void Console::commands::cl_find(NetworkState *state, pragma::BasePlayerComponent void CMD_fps(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { Con::cout << "FPS: " << util::round_string(c_engine->GetFPS(), 0) << Con::endl << "Frame Time: " << util::round_string(c_engine->GetFrameTime(), 2) << "ms" << Con::endl; } +static void write_to_file(const std::string &fileName, const std::optional &contents) +{ + if(!contents) { + Con::cwar << "Unable to dump '" << fileName << "': No contents available!" << Con::endl; + return; + } + if(!filemanager::write_file(fileName, *contents)) { + Con::cwar << "Unable to write '" << fileName << "'!" << Con::endl; + return; + } + Con::cout << "Dumped contents to '" << fileName << "'!" << Con::endl; +} void Console::commands::vk_dump_limits(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { - // prosper::debug::dump_limits(c_engine->GetRenderContext(),"vk_limits.txt"); + auto limits = c_engine->GetRenderContext().DumpLimits(); + write_to_file("vk_limits.txt", limits); } void Console::commands::vk_dump_features(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { - // prosper::debug::dump_features(c_engine->GetRenderContext(),"vk_features.txt"); + auto limits = c_engine->GetRenderContext().DumpFeatures(); + write_to_file("vk_features.txt", limits); } void Console::commands::vk_dump_format_properties(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { - // prosper::debug::dump_format_properties(c_engine->GetRenderContext(),"vk_format_properties.txt"); + auto limits = c_engine->GetRenderContext().DumpFormatProperties(); + write_to_file("vk_format_properties.txt", limits); } void Console::commands::vk_dump_image_format_properties(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { - // prosper::debug::dump_image_format_properties(c_engine->GetRenderContext(),"vk_image_format_properties.txt"); + auto limits = c_engine->GetRenderContext().DumpImageFormatProperties(); + write_to_file("vk_image_format_properties.txt", limits); } void Console::commands::vk_dump_layers(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { - // prosper::debug::dump_layers(c_engine->GetRenderContext(),"vk_layers.txt"); + auto limits = c_engine->GetRenderContext().DumpLayers(); + write_to_file("vk_layers.txt", limits); } void Console::commands::vk_dump_extensions(NetworkState *, pragma::BasePlayerComponent *, std::vector &) { - // prosper::debug::dump_extensions(c_engine->GetRenderContext(),"vk_extensions.txt"); + auto limits = c_engine->GetRenderContext().DumpExtensions(); + write_to_file("vk_extensions.txt", limits); } /*static void print_memory_stats(std::stringstream &ss,Vulkan::MemoryManager::StatInfo &info) { From 045624f63af6d016950fec810031b25d05cd0eaf Mon Sep 17 00:00:00 2001 From: Silverlan Date: Thu, 5 Dec 2024 21:41:53 +0100 Subject: [PATCH 43/64] build: update spirv-tools version --- build_scripts/build.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index 7501ca51b..854a6ed38 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -494,11 +494,11 @@ def execscript(filepath): if not Path(os.getcwd() +"/SPIRV-Tools").is_dir(): git_clone("https://github.com/KhronosGroup/SPIRV-Tools.git") os.chdir("SPIRV-Tools") - -# Note: When updating to a newer version, the SPIRV-Headers commit below has to match -# the one defined in https://github.com/KhronosGroup/SPIRV-Tools/blob/master/DEPS for the -# timestamp of this commit -reset_to_commit("7826e19") +# Note: See the branches on https://github.com/KhronosGroup/SPIRV-Tools to find the correct commit for +# the target Vulkan SDK version. +# When updating to a newer version, the SPIRV-Headers commit below has to match +# the one defined in https://github.com/KhronosGroup/SPIRV-Tools/blob//DEPS +reset_to_commit("6dcc7e350a0b9871a825414d42329e44b0eb8109") os.chdir("../../") ########## SPIRV-Headers ########## @@ -508,7 +508,7 @@ def execscript(filepath): if not Path(os.getcwd() +"/SPIRV-Headers").is_dir(): git_clone("https://github.com/KhronosGroup/SPIRV-Headers") os.chdir("SPIRV-Headers") -reset_to_commit("4995a2f2723c401eb0ea3e10c81298906bf1422b") +reset_to_commit("2a9b6f951c7d6b04b6c21fe1bf3f475b68b84801") os.chdir("../../") os.chdir("../../") From a86254107e37e692cea1a8ac7153d27fc62f85bd Mon Sep 17 00:00:00 2001 From: Silverlan Date: Thu, 5 Dec 2024 21:42:09 +0100 Subject: [PATCH 44/64] build: update submodules --- build_scripts/build.py | 2 +- build_scripts/scripts/external_libs.py | 2 +- build_scripts/scripts/modules.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index 854a6ed38..eca67f300 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -820,7 +820,7 @@ def execbuildscript(filepath): if with_essential_client_modules: add_pragma_module( name="pr_prosper_vulkan", - commitSha="b629cd60523450274277cfd353bc78f9aed4c2fa", + commitSha="f3ed8c366a3b29f46632b00afda549fd8a4266e4", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index da7dcbaca..875e93707 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","8610b68c467b5aee3ba97d8f797742b6ba612d5c") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","30e3efe0f1469d4044bf3f083d5dd98a1f7bbfda") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 4c4924842..1caaa54e4 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -12,6 +12,6 @@ get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b") -get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","b629cd60523450274277cfd353bc78f9aed4c2fa") +get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","f3ed8c366a3b29f46632b00afda549fd8a4266e4") os.chdir(curDir) From f476f6d62f4a47e3359eccb2f715cea3f6c9029b Mon Sep 17 00:00:00 2001 From: Silverlan Date: Thu, 5 Dec 2024 21:52:15 +0100 Subject: [PATCH 45/64] feat: custom layers can now be specified in render_api.udm --- core/client/src/c_engine.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 5485a5190..8abfa04b3 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -793,6 +793,16 @@ bool CEngine::Initialize(int argc, char *argv[]) udm::to_enum_value(pair.property, availability); contextCreateInfo.extensions[std::string {pair.key}] = availability; } + + std::vector layersAll; + std::vector layersApi; + data["all"]["layers"] >> layersAll; + data[renderAPI]["layers"] >> layersApi; + contextCreateInfo.layers.reserve(layersAll.size() + layersApi.size()); + for(auto &layer : layersAll) + contextCreateInfo.layers.push_back(layer); + for(auto &layer : layersApi) + contextCreateInfo.layers.push_back(layer); } if(windowRes) { From 94bbfa4faeb5c3fc819f9a79436aa9abf6bbf724 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 7 Dec 2024 08:11:10 +0100 Subject: [PATCH 46/64] feat: add crash_gpu console command for testing crash handlers --- assets/shaders/programs/util/crash.frag | 24 ++++++++++++++++++++++++ build_scripts/build.py | 2 +- build_scripts/scripts/external_libs.py | 2 +- build_scripts/scripts/modules.py | 2 +- core/client/src/c_engine_cmd.cpp | 13 +++++++++---- 5 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 assets/shaders/programs/util/crash.frag diff --git a/assets/shaders/programs/util/crash.frag b/assets/shaders/programs/util/crash.frag new file mode 100644 index 000000000..2a0c093d6 --- /dev/null +++ b/assets/shaders/programs/util/crash.frag @@ -0,0 +1,24 @@ +#version 440 + +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +layout(location = 0) in vec2 vs_vert_uv; + +layout(location = 0) out float fs_alpha; + +layout(LAYOUT_PUSH_CONSTANTS()) uniform PushConstants +{ + float offset; +} +u_pushConstants; + +void main() +{ + fs_alpha = 1.0; + while (fs_alpha > 0.0) + { + fs_alpha -= u_pushConstants.offset; + } + fs_alpha *= 0.1 * fs_alpha; +} diff --git a/build_scripts/build.py b/build_scripts/build.py index eca67f300..5c34fe91b 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -820,7 +820,7 @@ def execbuildscript(filepath): if with_essential_client_modules: add_pragma_module( name="pr_prosper_vulkan", - commitSha="f3ed8c366a3b29f46632b00afda549fd8a4266e4", + commitSha="1cab6a2cc1cfb5ab3f5e45e0b454d9638ef3e87f", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 875e93707..9df4b4d28 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","30e3efe0f1469d4044bf3f083d5dd98a1f7bbfda") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","c38390b43d2072bf0a9507d4218ea35b7af4785d") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 1caaa54e4..9517a0c8d 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -12,6 +12,6 @@ get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b") -get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","f3ed8c366a3b29f46632b00afda549fd8a4266e4") +get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","1cab6a2cc1cfb5ab3f5e45e0b454d9638ef3e87f") os.chdir(curDir) diff --git a/core/client/src/c_engine_cmd.cpp b/core/client/src/c_engine_cmd.cpp index 086a3c4f7..ecabf7ff6 100644 --- a/core/client/src/c_engine_cmd.cpp +++ b/core/client/src/c_engine_cmd.cpp @@ -146,6 +146,13 @@ void CEngine::RegisterConsoleCommands() *a = 1; }, ConVarFlags::None, "Forces the engine to crash."); + conVarMap.RegisterConCommand( + "crash_gpu", + [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { + Con::cwar << "GPU Crash command has been invoked. Crashing intentionally..." << Con::endl; + GetRenderContext().Crash(); + }, + ConVarFlags::None, "Forces a GPU crash."); conVarMap.RegisterConCommand( "debug_render_memory_budget", [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { @@ -232,8 +239,7 @@ void CEngine::RegisterConsoleCommands() Con::cout << "Done! Written shader files to '" << path << "'!" << Con::endl; }, ConVarFlags::None, "Dumps the glsl code for the specified shader."); - conVarMap.RegisterConCommand( - "debug_dump_render_queues", [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { g_dumpRenderQueues = true; }, ConVarFlags::None, "Prints all render queues for the next frame to the console."); + conVarMap.RegisterConCommand("debug_dump_render_queues", [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { g_dumpRenderQueues = true; }, ConVarFlags::None, "Prints all render queues for the next frame to the console."); conVarMap.RegisterConVar("debug_hide_gui", false, ConVarFlags::None, "Disables GUI rendering."); conVarMap.RegisterConVar("render_vsync_enabled", true, ConVarFlags::Archive, "Enables or disables vsync. OpenGL only."); @@ -487,8 +493,7 @@ void CEngine::RegisterConsoleCommands() } }); #endif - conVarMap.RegisterConCommand( - "asset_clear_unused_textures", [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { ClearUnusedAssets(pragma::asset::Type::Texture, true); }, ConVarFlags::None, "Clears all unused textures from memory."); + conVarMap.RegisterConCommand("asset_clear_unused_textures", [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { ClearUnusedAssets(pragma::asset::Type::Texture, true); }, ConVarFlags::None, "Clears all unused textures from memory."); conVarMap.RegisterConCommand( "vr_preinitialize", [this](NetworkState *state, pragma::BasePlayerComponent *, std::vector &argv, float) { From 957fa21af30521c5d3f08dcebc60611e4ddfa911 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 7 Dec 2024 15:10:54 +0100 Subject: [PATCH 47/64] feat: re-add vulkan debug information files to crashdumps --- core/client/src/c_engine.cpp | 53 ++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 8abfa04b3..aecceb8b8 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -314,35 +314,30 @@ void CEngine::DumpDebugInformation(uzip::ZIPFile &zip) const engineInfo << "Render API: " << GetRenderAPI(); zip.AddFile("engine_cl.txt", engineInfo.str()); -#if 0 - prosper::debug::dump_layers(c_engine->GetRenderContext(),ss); - zip.AddFile("vk_layers.txt",ss.str()); - - ss.str(std::string()); - ss.clear(); - prosper::debug::dump_extensions(c_engine->GetRenderContext(),ss); - zip.AddFile("vk_extensions.txt",ss.str()); - - ss.str(std::string()); - ss.clear(); - prosper::debug::dump_limits(c_engine->GetRenderContext(),ss); - zip.AddFile("vk_limits.txt",ss.str()); - - ss.str(std::string()); - ss.clear(); - prosper::debug::dump_features(c_engine->GetRenderContext(),ss); - zip.AddFile("vk_features.txt",ss.str()); - - ss.str(std::string()); - ss.clear(); - prosper::debug::dump_image_format_properties(c_engine->GetRenderContext(),ss); - zip.AddFile("vk_image_format_properties.txt",ss.str()); - - ss.str(std::string()); - ss.clear(); - prosper::debug::dump_format_properties(c_engine->GetRenderContext(),ss); - zip.AddFile("vk_format_properties.txt",ss.str()); -#endif + auto &context = c_engine->GetRenderContext(); + auto layers = context.DumpLayers(); + if(layers) + zip.AddFile("prosper_layers.txt", *layers); + + auto extensions = context.DumpExtensions(); + if(extensions) + zip.AddFile("prosper_extensions.txt", *extensions); + + auto limits = context.DumpLimits(); + if(limits) + zip.AddFile("prosper_limits.txt", *limits); + + auto features = context.DumpFeatures(); + if(features) + zip.AddFile("prosper_features.txt", *features); + + auto imageFormatProperties = context.DumpImageFormatProperties(); + if(imageFormatProperties) + zip.AddFile("prosper_image_format_properties.txt", *imageFormatProperties); + + auto formatProperties = context.DumpFormatProperties(); + if(formatProperties) + zip.AddFile("prosper_format_properties.txt", *formatProperties); } void CEngine::SetRenderResolution(std::optional resolution) From 7b6457cebd0637ed20e9ed8f52def169ec7326e6 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 7 Dec 2024 15:11:43 +0100 Subject: [PATCH 48/64] feat: change expected format of layers in render_api.udm --- core/client/src/c_engine.cpp | 117 +++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 12 deletions(-) diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index aecceb8b8..71f3c29a3 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -774,6 +774,7 @@ bool CEngine::Initialize(int argc, char *argv[]) renderApiData = udm::Data::Load("cfg/render_api.udm"); } catch(const udm::Exception &e) { + Con::cwar << "Failed to load render API data: " << e.what() << Con::endl; } if(renderApiData) { auto &renderAPI = GetRenderAPI(); @@ -783,21 +784,111 @@ bool CEngine::Initialize(int argc, char *argv[]) udm::to_enum_value(pair.property, availability); contextCreateInfo.extensions[std::string {pair.key}] = availability; } - for(auto &pair : data[renderAPI]["extensions"].ElIt()) { + for(auto &[key, prop] : data[renderAPI]["extensions"].ElIt()) { auto availability = prosper::IPrContext::ExtensionAvailability::EnableIfAvailable; - udm::to_enum_value(pair.property, availability); - contextCreateInfo.extensions[std::string {pair.key}] = availability; + udm::to_enum_value(prop, availability); + contextCreateInfo.extensions[std::string {key}] = availability; } - std::vector layersAll; - std::vector layersApi; - data["all"]["layers"] >> layersAll; - data[renderAPI]["layers"] >> layersApi; - contextCreateInfo.layers.reserve(layersAll.size() + layersApi.size()); - for(auto &layer : layersAll) - contextCreateInfo.layers.push_back(layer); - for(auto &layer : layersApi) - contextCreateInfo.layers.push_back(layer); + std::vector layers; + auto getLayerData = [&](udm::LinkedPropertyWrapper udmLayers) { + layers.reserve(layers.size() + udmLayers.GetSize()); + for(auto &layer : udmLayers) { + std::string name; + layer["name"] >> name; + if(name.empty()) + continue; + layers.push_back(name); + auto settings = layer["settings"]; + contextCreateInfo.layerSettings.reserve(contextCreateInfo.layerSettings.size() + settings.GetSize()); + for(auto &[key, prop] : settings.ElIt()) { + auto type = prop.GetType(); + prosper::LayerSetting setting {}; + setting.layerName = name; + setting.settingName = key; + if(type == udm::Type::Element) { + std::string settingType; + prop["type"] >> settingType; + auto udmValues = prop["values"]; + if(udmValues) { + auto *a = udmValues.GetValuePtr(); + if(a) { + auto size = a->GetSize(); + ::udm::visit(a->GetValueType(), [a, size, &setting, &settingType](auto tag) { + using T = typename decltype(tag)::type; + if constexpr(std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) { + auto *values = new T[size]; + for(size_t i = 0; i < size; ++i) + values[i] = a->GetValue(i); + setting.SetValues(size, values); + } + else if constexpr(std::is_same_v) { + if(settingType == "file") { + auto *values = new const char *[size]; + std::vector tmpPaths; + tmpPaths.reserve(size); + for(size_t i = 0; i < size; ++i) { + auto filePath = util::FilePath(util::get_program_path(), a->GetValue(i)); + tmpPaths.push_back(filePath); + values[i] = filePath.GetString().c_str(); + } + // SetValues copies the strings, so we can safely delete the temporary paths + setting.SetValues(size, values); + } + else { + auto *values = new const char *[size]; + for(size_t i = 0; i < size; ++i) + values[i] = a->GetValue(i).c_str(); + setting.SetValues(size, values); + } + } + else + throw std::invalid_argument {"Unsupported layer setting type " + std::string {magic_enum::enum_name(a->GetValueType())}}; + }); + } + } + else { + auto udmValue = prop["value"]; + ::udm::visit(udmValue.GetType(), [&udmValue, &setting, &settingType](auto tag) { + using T = typename decltype(tag)::type; + if constexpr(std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) + setting.SetValues(1, &udmValue.GetValue()); + else if constexpr(std::is_same_v) { + if(settingType == "file") { + auto filePath = util::FilePath(util::get_program_path(), udmValue.GetValue()); + auto *str = filePath.GetString().c_str(); + setting.SetValues(1, &str); + } + else { + auto *str = udmValue.GetValue().c_str(); + setting.SetValues(1, &str); + } + } + else + throw std::invalid_argument {"Unsupported layer setting type " + std::string {magic_enum::enum_name(udmValue.GetType())}}; + }); + } + } + else { + ::udm::visit(type, [&prop, &setting](auto tag) { + using T = typename decltype(tag)::type; + if constexpr(std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v) + setting.SetValues(1, &prop.GetValue()); + else if constexpr(std::is_same_v) { + auto *str = prop.GetValue().c_str(); + setting.SetValues(1, &str); + } + else + throw std::invalid_argument {"Unsupported layer setting type " + std::string {magic_enum::enum_name(prop.GetType())}}; + }); + } + contextCreateInfo.layerSettings.push_back(setting); + } + } + }; + getLayerData(data["all"]["layers"]); + getLayerData(data[renderAPI]["layers"]); + contextCreateInfo.layers = std::move(layers); } if(windowRes) { @@ -1056,9 +1147,11 @@ bool CEngine::Initialize(int argc, char *argv[]) if(r == IDCANCEL) ShutDown(); } + #endif return true; } + const std::string &CEngine::GetDefaultFontSetName() const { return m_defaultFontSet; } const FontSet &CEngine::GetDefaultFontSet() const { From 0ea4f89595e6f4df6a2b94563ceed124a66793c3 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sat, 7 Dec 2024 15:15:25 +0100 Subject: [PATCH 49/64] feat: move nsight aftermath to module ( Silverlan/pr_nsight_aftermath ) --- build_scripts/build.py | 11 +- build_scripts/scripts/external_libs.py | 2 +- build_scripts/scripts/modules.py | 2 +- .../include/pragma/debug/nsight_aftermath.hpp | 211 ----------- core/client/src/c_engine.cpp | 6 - core/client/src/debug/nsight_aftermath.cpp | 327 ------------------ .../client/src/rendering/c_render_context.cpp | 12 +- 7 files changed, 21 insertions(+), 550 deletions(-) delete mode 100644 core/client/include/pragma/debug/nsight_aftermath.hpp delete mode 100644 core/client/src/debug/nsight_aftermath.cpp diff --git a/build_scripts/build.py b/build_scripts/build.py index 5c34fe91b..bb6d35ec7 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -767,7 +767,8 @@ def execbuildscript(filepath): "execbuildscript": execbuildscript, "str2bool": str2bool, "install_prebuilt_binaries": install_prebuilt_binaries, - "reset_to_commit": reset_to_commit + "reset_to_commit": reset_to_commit, + "add_pragma_module": add_pragma_module } if platform == "linux": l["c_compiler"] = c_compiler @@ -820,7 +821,7 @@ def execbuildscript(filepath): if with_essential_client_modules: add_pragma_module( name="pr_prosper_vulkan", - commitSha="1cab6a2cc1cfb5ab3f5e45e0b454d9638ef3e87f", + commitSha="b878be11c48f9b6e11fae8b4395b3ba78551569b", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) @@ -914,7 +915,10 @@ def execbuildscript(filepath): # CMake configuration explicitly if they should be disabled. shippedModules = ["pr_audio_dummy","pr_prosper_opengl","pr_prosper_vulkan","pr_curl"] -for module in module_info: +index = 0 +# The module list can be modified during iteration, so we have to use a while loop here. +while index < len(module_info): + module = module_info[index] global moduleName moduleName = module["name"] moduleUrl = module["repositoryUrl"] @@ -945,6 +949,7 @@ def execbuildscript(filepath): if not skipBuildTarget: module_list.append(moduleName) + index += 1 for module in shippedModules: if module != "pr_curl": # Curl is currently required diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index 9df4b4d28..e597ae880 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","c38390b43d2072bf0a9507d4218ea35b7af4785d") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","958b514432224057fb9af6d530eeaeb236cd3656") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 9517a0c8d..964e33c6c 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -12,6 +12,6 @@ get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b") -get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","1cab6a2cc1cfb5ab3f5e45e0b454d9638ef3e87f") +get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","b878be11c48f9b6e11fae8b4395b3ba78551569b") os.chdir(curDir) diff --git a/core/client/include/pragma/debug/nsight_aftermath.hpp b/core/client/include/pragma/debug/nsight_aftermath.hpp deleted file mode 100644 index d999305a9..000000000 --- a/core/client/include/pragma/debug/nsight_aftermath.hpp +++ /dev/null @@ -1,211 +0,0 @@ -//********************************************************* -// -// Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -//********************************************************* - -#pragma once - -// See the following for more information: -// https://github.com/NVIDIA/nsight-aftermath-samples/tree/master/VkHelloNsightAftermath -// https://developer.nvidia.com/nsight-aftermath - -// #define PRAGMA_ENABLE_NSIGHT_AFTERMATH -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH - -// #define NSIGHT_ENABLE_SHADER_DATABASE - -#include "pragma/clientdefinitions.h" -#include -#include -#include -#include -#include -#include -#include -#include - -//********************************************************* -// Some std::to_string overloads for some Nsight Aftermath -// API types. -// - -namespace std { - template - inline std::string to_hex_string(T n) - { - std::stringstream stream; - stream << std::setfill('0') << std::setw(2 * sizeof(T)) << std::hex << n; - return stream.str(); - } - - inline std::string to_string(GFSDK_Aftermath_Result result) { return std::string("0x") + to_hex_string(static_cast(result)); } - - inline std::string to_string(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &identifier) { return to_hex_string(identifier.id[0]) + "-" + to_hex_string(identifier.id[1]); } - - inline std::string to_string(const GFSDK_Aftermath_ShaderBinaryHash &hash) { return to_hex_string(hash.hash); } -} // namespace std - -inline std::string AftermathErrorMessage(GFSDK_Aftermath_Result result) -{ - switch(result) { - case GFSDK_Aftermath_Result_FAIL_DriverVersionNotSupported: - return "Unsupported driver version - requires an NVIDIA R495 display driver or newer."; - default: - return "Aftermath Error 0x" + std::to_hex_string(result); - } -} - -// Helper macro for checking Nsight Aftermath results and throwing exception -// in case of a failure. -#ifdef _WIN32 -#define AFTERMATH_CHECK_ERROR(FC) \ - [&]() { \ - GFSDK_Aftermath_Result _result = FC; \ - if(!GFSDK_Aftermath_SUCCEED(_result)) { \ - MessageBoxA(0, AftermathErrorMessage(_result).c_str(), "Aftermath Error", MB_OK); \ - exit(1); \ - } \ - }() -#else -#define AFTERMATH_CHECK_ERROR(FC) \ - [&]() { \ - GFSDK_Aftermath_Result _result = FC; \ - if(!GFSDK_Aftermath_SUCCEED(_result)) { \ - printf("%s\n", AftermathErrorMessage(_result).c_str()); \ - fflush(stdout); \ - exit(1); \ - } \ - }() -#endif - -// Helper for comparing GFSDK_Aftermath_ShaderDebugInfoIdentifier. -inline bool operator<(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &lhs, const GFSDK_Aftermath_ShaderDebugInfoIdentifier &rhs) -{ - if(lhs.id[0] == rhs.id[0]) { - return lhs.id[1] < rhs.id[1]; - } - return lhs.id[0] < rhs.id[0]; -} - -//********************************************************* -// Implements GPU crash dump tracking using the Nsight -// Aftermath API. -// -class GpuCrashTracker { - public: - // keep four frames worth of marker history - const static unsigned int c_markerFrameHistory = 4; - typedef std::array, c_markerFrameHistory> MarkerMap; - - GpuCrashTracker(const MarkerMap &markerMap); - ~GpuCrashTracker(); - - // Initialize the GPU crash dump tracker. - void Initialize(); - private: - //********************************************************* - // Callback handlers for GPU crash dumps and related data. - // - - // Handler for GPU crash dump callbacks. - void OnCrashDump(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize); - - // Handler for shader debug information callbacks. - void OnShaderDebugInfo(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize); - - // Handler for GPU crash dump description callbacks. - void OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription); - - // Handler for app-managed marker resolve callback - void OnResolveMarker(const void *pMarker, void **resolvedMarkerData, uint32_t *markerSize); - - //********************************************************* - // Helpers for writing a GPU crash dump and debug information - // data to files. - // - - // Helper for writing a GPU crash dump to a file. - void WriteGpuCrashDumpToFile(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize); - - // Helper for writing shader debug information to a file - void WriteShaderDebugInformationToFile(GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier, const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize); - - //********************************************************* - // Helpers for decoding GPU crash dump to JSON. - // - - // Handler for shader debug info lookup callbacks. - void OnShaderDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &identifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo) const; - - // Handler for shader lookup callbacks. - void OnShaderLookup(const GFSDK_Aftermath_ShaderBinaryHash &shaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary) const; - - // Handler for shader source debug info lookup callbacks. - void OnShaderSourceDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugName &shaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary) const; - - //********************************************************* - // Static callback wrappers. - // - - // GPU crash dump callback. - static void GpuCrashDumpCallback(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize, void *pUserData); - - // Shader debug information callback. - static void ShaderDebugInfoCallback(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize, void *pUserData); - - // GPU crash dump description callback. - static void CrashDumpDescriptionCallback(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription, void *pUserData); - - // App-managed marker resolve callback - static void ResolveMarkerCallback(const void *pMarker, void *pUserData, void **resolvedMarkerData, uint32_t *markerSize); - - // Shader debug information lookup callback. - static void ShaderDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugInfoIdentifier *pIdentifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo, void *pUserData); - - // Shader lookup callback. - static void ShaderLookupCallback(const GFSDK_Aftermath_ShaderBinaryHash *pShaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData); - - // Shader source debug info lookup callback. - static void ShaderSourceDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugName *pShaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData); - - //********************************************************* - // GPU crash tracker state. - // - - // Is the GPU crash dump tracker initialized? - bool m_initialized; - - // For thread-safe access of GPU crash tracker state. - mutable std::mutex m_mutex; - - // List of Shader Debug Information by ShaderDebugInfoIdentifier. - std::map> m_shaderDebugInfo; - - // The mock shader database. -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - ShaderDatabase m_shaderDatabase; -#endif - - // App-managed marker tracking - const MarkerMap &m_markerMap; -}; -#endif diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 71f3c29a3..dd90cfa19 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -91,9 +91,6 @@ void DLLCLIENT RunCEngine(int argc, char *argv[]) en = nullptr; } } -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH -void enable_nsight_aftermath_crash_tracker(); -#endif DLLCLIENT CEngine *c_engine = NULL; extern DLLCLIENT ClientState *client; @@ -124,9 +121,6 @@ CEngine::CEngine(int argc, char *argv[]) m_farZ(pragma::BaseEnvCameraComponent::DEFAULT_FAR_Z), m_fps(0), m_tFPSTime(0.f), m_tLastFrame(util::Clock::now()), m_tDeltaFrameTime(0), m_audioAPI {"fmod"} { c_engine = this; -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH - enable_nsight_aftermath_crash_tracker(); -#endif RegisterCallback, bool>("OnJoystickStateChanged"); RegisterCallback>>("DrawFrame"); RegisterCallback("PreDrawGUI"); diff --git a/core/client/src/debug/nsight_aftermath.cpp b/core/client/src/debug/nsight_aftermath.cpp deleted file mode 100644 index 1075fcebd..000000000 --- a/core/client/src/debug/nsight_aftermath.cpp +++ /dev/null @@ -1,327 +0,0 @@ -//********************************************************* -// -// Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -//********************************************************* - -#include "stdafx_client.h" -#include "pragma/debug/nsight_aftermath.hpp" - -#ifdef PRAGMA_ENABLE_NSIGHT_AFTERMATH -#include -#include -#include -#include -#pragma optimize("", off) -//********************************************************* -// GpuCrashTracker implementation -//********************************************************* - -#pragma comment(lib, "E:/projects/NVIDIA_Nsight_Aftermath_SDK_2023.1.0.23076/lib/x64/GFSDK_Aftermath_Lib.x64.lib") -GpuCrashTracker::GpuCrashTracker(const MarkerMap &markerMap) - : m_initialized(false), m_mutex(), m_shaderDebugInfo(), m_markerMap(markerMap) -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - , - m_shaderDatabase() -#endif -{ -} - -GpuCrashTracker::~GpuCrashTracker() -{ - // If initialized, disable GPU crash dumps - if(m_initialized) { - GFSDK_Aftermath_DisableGpuCrashDumps(); - } -} - -// Initialize the GPU Crash Dump Tracker -void GpuCrashTracker::Initialize() -{ - // Enable GPU crash dumps and set up the callbacks for crash dump notifications, - // shader debug information notifications, and providing additional crash - // dump description data.Only the crash dump callback is mandatory. The other two - // callbacks are optional and can be omitted, by passing nullptr, if the corresponding - // functionality is not used. - // The DeferDebugInfoCallbacks flag enables caching of shader debug information data - // in memory. If the flag is set, ShaderDebugInfoCallback will be called only - // in the event of a crash, right before GpuCrashDumpCallback. If the flag is not set, - // ShaderDebugInfoCallback will be called for every shader that is compiled. - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_EnableGpuCrashDumps(GFSDK_Aftermath_Version_API, GFSDK_Aftermath_GpuCrashDumpWatchedApiFlags_Vulkan, - GFSDK_Aftermath_GpuCrashDumpFeatureFlags_DeferDebugInfoCallbacks, // Let the Nsight Aftermath library cache shader debug information. - GpuCrashDumpCallback, // Register callback for GPU crash dumps. - ShaderDebugInfoCallback, // Register callback for shader debug information. - CrashDumpDescriptionCallback, // Register callback for GPU crash dump description. - ResolveMarkerCallback, // Register callback for resolving application-managed markers. - this)); // Set the GpuCrashTracker object as user data for the above callbacks. - - m_initialized = true; -} - -// Handler for GPU crash dump callbacks from Nsight Aftermath -void GpuCrashTracker::OnCrashDump(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize) -{ - // Make sure only one thread at a time... - std::lock_guard lock(m_mutex); - - // Write to file for later in-depth analysis with Nsight Graphics. - WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize); -} - -// Handler for shader debug information callbacks -void GpuCrashTracker::OnShaderDebugInfo(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize) -{ - // Make sure only one thread at a time... - std::lock_guard lock(m_mutex); - - // Get shader debug information identifier - GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {}; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GetShaderDebugInfoIdentifier(GFSDK_Aftermath_Version_API, pShaderDebugInfo, shaderDebugInfoSize, &identifier)); - - // Store information for decoding of GPU crash dumps with shader address mapping - // from within the application. - std::vector data((uint8_t *)pShaderDebugInfo, (uint8_t *)pShaderDebugInfo + shaderDebugInfoSize); - m_shaderDebugInfo[identifier].swap(data); - - // Write to file for later in-depth analysis of crash dumps with Nsight Graphics - WriteShaderDebugInformationToFile(identifier, pShaderDebugInfo, shaderDebugInfoSize); -} - -// Handler for GPU crash dump description callbacks -void GpuCrashTracker::OnDescription(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription) -{ - // Add some basic description about the crash. This is called after the GPU crash happens, but before - // the actual GPU crash dump callback. The provided data is included in the crash dump and can be - // retrieved using GFSDK_Aftermath_GpuCrashDump_GetDescription(). - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, "VkHelloNsightAftermath"); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationVersion, "v1.0"); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined, "This is a GPU crash dump example."); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined + 1, "Engine State: Rendering."); - addDescription(GFSDK_Aftermath_GpuCrashDumpDescriptionKey_UserDefined + 2, "More user-defined information..."); -} - -// Handler for app-managed marker resolve callback -void GpuCrashTracker::OnResolveMarker(const void *pMarker, void **resolvedMarkerData, uint32_t *markerSize) -{ - // Important: the pointer passed back via resolvedMarkerData must remain valid after this function returns - // using references for all of the m_markerMap accesses ensures that the pointers refer to the persistent data - for(auto &map : m_markerMap) { - const auto &foundMarker = map.find((uint64_t)pMarker); - if(foundMarker != map.end()) { - const std::string &markerData = foundMarker->second; - // std::string::data() will return a valid pointer until the string is next modified - // we don't modify the string after calling data() here, so the pointer should remain valid - *resolvedMarkerData = (void *)markerData.data(); - *markerSize = (uint32_t)markerData.length(); - return; - } - } -} - -// Helper for writing a GPU crash dump to a file -void GpuCrashTracker::WriteGpuCrashDumpToFile(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize) -{ - // Create a GPU crash dump decoder object for the GPU crash dump. - GFSDK_Aftermath_GpuCrashDump_Decoder decoder = {}; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_CreateDecoder(GFSDK_Aftermath_Version_API, pGpuCrashDump, gpuCrashDumpSize, &decoder)); - - // Use the decoder object to read basic information, like application - // name, PID, etc. from the GPU crash dump. - GFSDK_Aftermath_GpuCrashDump_BaseInfo baseInfo = {}; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetBaseInfo(decoder, &baseInfo)); - - // Use the decoder object to query the application name that was set - // in the GPU crash dump description. - uint32_t applicationNameLength = 0; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetDescriptionSize(decoder, GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, &applicationNameLength)); - - std::vector applicationName(applicationNameLength, '\0'); - - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetDescription(decoder, GFSDK_Aftermath_GpuCrashDumpDescriptionKey_ApplicationName, uint32_t(applicationName.size()), applicationName.data())); - - // Create a unique file name for writing the crash dump data to a file. - // Note: due to an Nsight Aftermath bug (will be fixed in an upcoming - // driver release) we may see redundant crash dumps. As a workaround, - // attach a unique count to each generated file name. - static int count = 0; - const std::string baseFileName = std::string(applicationName.data()) + "-" + std::to_string(baseInfo.pid) + "-" + std::to_string(++count); - - // Write the crash dump data to a file using the .nv-gpudmp extension - // registered with Nsight Graphics. - filemanager::create_directory("crashdumps"); - auto path = util::Path::CreatePath(util::get_program_path()) + "crashdumps/"; - const std::string crashDumpFileName = baseFileName + ".nv-gpudmp"; - auto fullPath = path.GetString() + crashDumpFileName; - std::ofstream dumpFile(fullPath, std::ios::out | std::ios::binary); - if(dumpFile) { - dumpFile.write((const char *)pGpuCrashDump, gpuCrashDumpSize); - dumpFile.close(); - } - - // Decode the crash dump to a JSON string. - // Step 1: Generate the JSON and get the size. - uint32_t jsonSize = 0; - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GenerateJSON(decoder, GFSDK_Aftermath_GpuCrashDumpDecoderFlags_ALL_INFO, GFSDK_Aftermath_GpuCrashDumpFormatterFlags_NONE, ShaderDebugInfoLookupCallback, ShaderLookupCallback, ShaderSourceDebugInfoLookupCallback, this, &jsonSize)); - // Step 2: Allocate a buffer and fetch the generated JSON. - std::vector json(jsonSize); - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_GetJSON(decoder, uint32_t(json.size()), json.data())); - - // Write the crash dump data as JSON to a file. - const std::string jsonFileName = fullPath + ".json"; - std::ofstream jsonFile(jsonFileName, std::ios::out | std::ios::binary); - if(jsonFile) { - // Write the JSON to the file (excluding string termination) - jsonFile.write(json.data(), json.size() - 1); - jsonFile.close(); - } - - // Destroy the GPU crash dump decoder object. - AFTERMATH_CHECK_ERROR(GFSDK_Aftermath_GpuCrashDump_DestroyDecoder(decoder)); -} - -// Helper for writing shader debug information to a file -void GpuCrashTracker::WriteShaderDebugInformationToFile(GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier, const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize) -{ - // Create a unique file name. - const std::string filePath = "shader-" + std::to_string(identifier) + ".nvdbg"; - - std::ofstream f(filePath, std::ios::out | std::ios::binary); - if(f) { - f.write((const char *)pShaderDebugInfo, shaderDebugInfoSize); - } -} - -// Handler for shader debug information lookup callbacks. -// This is used by the JSON decoder for mapping shader instruction -// addresses to SPIR-V IL lines or GLSL source lines. -void GpuCrashTracker::OnShaderDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugInfoIdentifier &identifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo) const -{ - // Search the list of shader debug information blobs received earlier. - auto i_debugInfo = m_shaderDebugInfo.find(identifier); - if(i_debugInfo == m_shaderDebugInfo.end()) { - // Early exit, nothing found. No need to call setShaderDebugInfo. - return; - } - - // Let the GPU crash dump decoder know about the shader debug information - // that was found. - setShaderDebugInfo(i_debugInfo->second.data(), uint32_t(i_debugInfo->second.size())); -} - -// Handler for shader lookup callbacks. -// This is used by the JSON decoder for mapping shader instruction -// addresses to SPIR-V IL lines or GLSL source lines. -// NOTE: If the application loads stripped shader binaries (ie; --strip-all in spirv-remap), -// Aftermath will require access to both the stripped and the not stripped -// shader binaries. -void GpuCrashTracker::OnShaderLookup(const GFSDK_Aftermath_ShaderBinaryHash &shaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary) const -{ -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - // Find shader binary data for the shader hash in the shader database. - std::vector shaderBinary; - if(!m_shaderDatabase.FindShaderBinary(shaderHash, shaderBinary)) { - // Early exit, nothing found. No need to call setShaderBinary. - return; - } - - // Let the GPU crash dump decoder know about the shader data - // that was found. - setShaderBinary(shaderBinary.data(), uint32_t(shaderBinary.size())); -#endif -} - -// Handler for shader source debug info lookup callbacks. -// This is used by the JSON decoder for mapping shader instruction addresses to -// GLSL source lines, if the shaders used by the application were compiled with -// separate debug info data files. -void GpuCrashTracker::OnShaderSourceDebugInfoLookup(const GFSDK_Aftermath_ShaderDebugName &shaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary) const -{ -#ifdef NSIGHT_ENABLE_SHADER_DATABASE - // Find source debug info for the shader DebugName in the shader database. - std::vector shaderBinary; - if(!m_shaderDatabase.FindShaderBinaryWithDebugData(shaderDebugName, shaderBinary)) { - // Early exit, nothing found. No need to call setShaderBinary. - return; - } - - // Let the GPU crash dump decoder know about the shader debug data that was - // found. - setShaderBinary(shaderBinary.data(), uint32_t(shaderBinary.size())); -#endif -} - -// Static callback wrapper for OnCrashDump -void GpuCrashTracker::GpuCrashDumpCallback(const void *pGpuCrashDump, const uint32_t gpuCrashDumpSize, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnCrashDump(pGpuCrashDump, gpuCrashDumpSize); -} - -// Static callback wrapper for OnShaderDebugInfo -void GpuCrashTracker::ShaderDebugInfoCallback(const void *pShaderDebugInfo, const uint32_t shaderDebugInfoSize, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderDebugInfo(pShaderDebugInfo, shaderDebugInfoSize); -} - -// Static callback wrapper for OnDescription -void GpuCrashTracker::CrashDumpDescriptionCallback(PFN_GFSDK_Aftermath_AddGpuCrashDumpDescription addDescription, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnDescription(addDescription); -} - -// Static callback wrapper for OnResolveMarker -void GpuCrashTracker::ResolveMarkerCallback(const void *pMarker, void *pUserData, void **resolvedMarkerData, uint32_t *markerSize) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnResolveMarker(pMarker, resolvedMarkerData, markerSize); -} - -// Static callback wrapper for OnShaderDebugInfoLookup -void GpuCrashTracker::ShaderDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugInfoIdentifier *pIdentifier, PFN_GFSDK_Aftermath_SetData setShaderDebugInfo, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderDebugInfoLookup(*pIdentifier, setShaderDebugInfo); -} - -// Static callback wrapper for OnShaderLookup -void GpuCrashTracker::ShaderLookupCallback(const GFSDK_Aftermath_ShaderBinaryHash *pShaderHash, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderLookup(*pShaderHash, setShaderBinary); -} - -// Static callback wrapper for OnShaderSourceDebugInfoLookup -void GpuCrashTracker::ShaderSourceDebugInfoLookupCallback(const GFSDK_Aftermath_ShaderDebugName *pShaderDebugName, PFN_GFSDK_Aftermath_SetData setShaderBinary, void *pUserData) -{ - GpuCrashTracker *pGpuCrashTracker = reinterpret_cast(pUserData); - pGpuCrashTracker->OnShaderSourceDebugInfoLookup(*pShaderDebugName, setShaderBinary); -} - -void enable_nsight_aftermath_crash_tracker() -{ - static GpuCrashTracker::MarkerMap markerMap; - static GpuCrashTracker tracker {markerMap}; - tracker.Initialize(); -} - -#endif diff --git a/core/client/src/rendering/c_render_context.cpp b/core/client/src/rendering/c_render_context.cpp index 914d9615d..001c3f273 100644 --- a/core/client/src/rendering/c_render_context.cpp +++ b/core/client/src/rendering/c_render_context.cpp @@ -8,6 +8,7 @@ #include "stdafx_cengine.h" #include "pragma/rendering/c_render_context.hpp" #include "pragma/rendering/render_apis.hpp" +#include "pragma/debug/debug_utils.hpp" #include #include #include @@ -28,7 +29,15 @@ static spdlog::logger &LOGGER = pragma::register_logger("prosper"); static spdlog::logger &LOGGER_VALIDATION = pragma::register_logger("prosper_validation"); RenderContext::RenderContext() : m_monitor(nullptr), m_renderAPI {"vulkan"} {} -RenderContext::~RenderContext() { m_graphicsAPILib = nullptr; } +RenderContext::~RenderContext() +{ + if(m_graphicsAPILib) { + auto *detach = m_graphicsAPILib->FindSymbolAddress("pragma_detach"); + if(detach) + detach(); + } + m_graphicsAPILib = nullptr; +} DLLNETWORK std::optional g_customTitle; extern bool g_cpuRendering; void RenderContext::InitializeRenderAPI() @@ -99,6 +108,7 @@ void RenderContext::InitializeRenderAPI() } m_renderContext->SetLogHandler(&pragma::log, &pragma::is_log_level_enabled); + m_renderContext->SetProfilingHandler([](const char *taskName) { pragma::debug::start_profiling_task(taskName); }, []() { pragma::debug::end_profiling_task(); }); prosper::Callbacks callbacks {}; callbacks.validationCallback = [this](prosper::DebugMessageSeverityFlags severityFlags, const std::string &message) { ValidationCallback(severityFlags, message); }; From f37f3e9e0170b9e2b3687a4dcb715ead8340401f Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sun, 8 Dec 2024 19:11:06 +0100 Subject: [PATCH 50/64] feat: add crash diagnostic render api configuration The VK_LAYER_LUNARG_crash_diagnostic is currently in an alpha state and not yet functional. Once it's out of alpha, this file should be renamed to "render_api.udm" to enable it. --- assets/cfg/render_api_crash_diagnostic.udm | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 assets/cfg/render_api_crash_diagnostic.udm diff --git a/assets/cfg/render_api_crash_diagnostic.udm b/assets/cfg/render_api_crash_diagnostic.udm new file mode 100644 index 000000000..30f8d6d22 --- /dev/null +++ b/assets/cfg/render_api_crash_diagnostic.udm @@ -0,0 +1,26 @@ +"vulkan" +{ + $array layers [element;1][ + { + $string name "VK_LAYER_LUNARG_crash_diagnostic" + settings + { + log_file + { + $string type "file" + $string value "crashdumps/log.txt" + } + output_path + { + $string type "file" + $string value "crashdumps" + } + $string dump_shaders "on_crash" + $string dump_commands "running" + $string dump_command_buffers "running" + $string dump_queue_submissions "running" + $bool trace_on 1 + } + } + ] +} From 35bbc213615a52a871938de77f1a092af845d4dc Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sun, 8 Dec 2024 19:15:57 +0100 Subject: [PATCH 51/64] build: add convenience build scripts --- build.bat | 2 ++ build.sh | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 build.bat create mode 100644 build.sh diff --git a/build.bat b/build.bat new file mode 100644 index 000000000..83f224dd3 --- /dev/null +++ b/build.bat @@ -0,0 +1,2 @@ +python build_scripts/build.py +pause \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 000000000..434df0386 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +python3 build_scripts/build.py +read -p "Press [Enter] key to continue..." From 1f8b208037c4f811bf23ddffc55b0798d75dab15 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sun, 8 Dec 2024 19:17:04 +0100 Subject: [PATCH 52/64] fix: render api library not being cleaned up properly --- core/client/src/rendering/c_render_context.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/core/client/src/rendering/c_render_context.cpp b/core/client/src/rendering/c_render_context.cpp index 001c3f273..918aa9107 100644 --- a/core/client/src/rendering/c_render_context.cpp +++ b/core/client/src/rendering/c_render_context.cpp @@ -29,15 +29,7 @@ static spdlog::logger &LOGGER = pragma::register_logger("prosper"); static spdlog::logger &LOGGER_VALIDATION = pragma::register_logger("prosper_validation"); RenderContext::RenderContext() : m_monitor(nullptr), m_renderAPI {"vulkan"} {} -RenderContext::~RenderContext() -{ - if(m_graphicsAPILib) { - auto *detach = m_graphicsAPILib->FindSymbolAddress("pragma_detach"); - if(detach) - detach(); - } - m_graphicsAPILib = nullptr; -} +RenderContext::~RenderContext() {} DLLNETWORK std::optional g_customTitle; extern bool g_cpuRendering; void RenderContext::InitializeRenderAPI() @@ -157,6 +149,13 @@ void RenderContext::Release() return; GetRenderContext().Close(); m_renderContext = nullptr; + + if(m_graphicsAPILib) { + auto *detach = m_graphicsAPILib->FindSymbolAddress("pragma_detach"); + if(detach) + detach(); + } + m_graphicsAPILib = nullptr; } const prosper::IPrContext &RenderContext::GetRenderContext() const { return const_cast(this)->GetRenderContext(); } prosper::IPrContext &RenderContext::GetRenderContext() { return *m_renderContext; } From 99068da293eea9e21aa7647953d5311c9954b77b Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sun, 8 Dec 2024 19:18:03 +0100 Subject: [PATCH 53/64] build: update submodules --- build_scripts/build.py | 2 +- build_scripts/scripts/external_libs.py | 4 ++-- build_scripts/scripts/modules.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build_scripts/build.py b/build_scripts/build.py index bb6d35ec7..53e21126f 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -821,7 +821,7 @@ def execbuildscript(filepath): if with_essential_client_modules: add_pragma_module( name="pr_prosper_vulkan", - commitSha="b878be11c48f9b6e11fae8b4395b3ba78551569b", + commitSha="3b526679f38354cfc605fba93da3ed7727eaca36", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) diff --git a/build_scripts/scripts/external_libs.py b/build_scripts/scripts/external_libs.py index e597ae880..11e6cc9c1 100644 --- a/build_scripts/scripts/external_libs.py +++ b/build_scripts/scripts/external_libs.py @@ -16,7 +16,7 @@ get_submodule("mathutil","https://github.com/Silverlan/mathutil.git","e872f599805cf696ff6a84a4253fc44ae8e83a15") get_submodule("networkmanager","https://github.com/Silverlan/networkmanager.git","981bc5809c1a768267ddace778205e1be0262730") get_submodule("panima","https://github.com/Silverlan/panima.git","06916dd30cde319f31b1eee25cfed7dea8f14630") -get_submodule("prosper","https://github.com/Silverlan/prosper.git","958b514432224057fb9af6d530eeaeb236cd3656") +get_submodule("prosper","https://github.com/Silverlan/prosper.git","d39a127688792194d8075ad85dd7b4312b49ff11") get_submodule("sharedutils","https://github.com/Silverlan/sharedutils.git","65031009e7f85722f243a493ad47e03ca10617fe") get_submodule("util_bsp","https://github.com/Silverlan/util_bsp.git","2d912cceaaa59199a86431aa9d194e922b2ebea4") get_submodule("util_formatted_text","https://github.com/Silverlan/util_formatted_text.git","c473a2bdc1ad84ef52d391226d6983ef3076958e") @@ -33,7 +33,7 @@ get_submodule("util_vmf","https://github.com/Silverlan/util_vmf.git","4e477b1425e1a7b9898975effaf527f661e792da") get_submodule("util_zip","https://github.com/Silverlan/util_zip.git","d9bf05a5cbf71bf53f9fbea82c7352f870989ed1") get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","4cfd882fd49632843149750c8f60ce10ba5c3e77") -get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") +get_submodule("vfilesystem","https://github.com/Silverlan/vfilesystem.git","a150f67ab21993715d116bc31faaa2da5923e37e") get_submodule("wgui","https://github.com/Silverlan/wgui.git","edf2c8badee0012274da4ec4a4b2c45223218b90") get_submodule("util_unicode","https://github.com/Silverlan/util_unicode.git","5a0ac6c02f199e42d7d38d99231503cf42e26f8a") get_submodule("cppbezierfit","https://github.com/Silverlan/cppbezierfit.git","b1f76c0187411230ebe59fa606292b0947e730b6") diff --git a/build_scripts/scripts/modules.py b/build_scripts/scripts/modules.py index 964e33c6c..efac3d095 100644 --- a/build_scripts/scripts/modules.py +++ b/build_scripts/scripts/modules.py @@ -12,6 +12,6 @@ get_submodule("pr_audio_dummy","https://github.com/Silverlan/pr_audio_dummy.git","1a806a1a7b2283bd8551d07e4f1d680499f68b90") get_submodule("pr_curl","https://github.com/Silverlan/pr_curl.git","974c67cc76710809a9595fcfbc4167554799cd7f") get_submodule("pr_prosper_opengl","https://github.com/Silverlan/pr_prosper_opengl.git","9cf6bc0b8b26cbd044c2e202dc9be57cc87e7e1b") -get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","b878be11c48f9b6e11fae8b4395b3ba78551569b") +get_submodule("pr_prosper_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","3b526679f38354cfc605fba93da3ed7727eaca36") os.chdir(curDir) From 7b437b2ea3aba6d52c44209a4c6dda62dc9a070b Mon Sep 17 00:00:00 2001 From: Silverlan Date: Sun, 8 Dec 2024 19:19:23 +0100 Subject: [PATCH 54/64] feat: add launch option -enable_gfx_diagnostics --- .../client/include/pragma/rendering/c_render_context.hpp | 9 ++++++++- core/client/src/c_launchparameters.cpp | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/core/client/include/pragma/rendering/c_render_context.hpp b/core/client/include/pragma/rendering/c_render_context.hpp index c87d8b60d..78d652345 100644 --- a/core/client/include/pragma/rendering/c_render_context.hpp +++ b/core/client/include/pragma/rendering/c_render_context.hpp @@ -29,7 +29,11 @@ namespace prosper { namespace pragma { class DLLCLIENT RenderContext { public: - enum class StateFlags : uint8_t { None = 0u, GfxAPIValidationEnabled = 1u }; + enum class StateFlags : uint8_t { + None = 0u, + GfxAPIValidationEnabled = 1u, + GfxDiagnosticsModeEnabled = GfxAPIValidationEnabled << 1u, + }; RenderContext(); virtual ~RenderContext(); @@ -53,6 +57,9 @@ namespace pragma { void InitializeRenderAPI(); void SetGfxAPIValidationEnabled(bool b); + void SetGfxDiagnosticsModeEnabled(bool b); + bool IsGfxAPIValidationEnabled() const; + bool IsGfxDiagnosticsModeEnabled() const; void SetRenderAPI(const std::string &renderAPI); const std::string &GetRenderAPI() const; diff --git a/core/client/src/c_launchparameters.cpp b/core/client/src/c_launchparameters.cpp index 672f045f7..26ffbdc64 100644 --- a/core/client/src/c_launchparameters.cpp +++ b/core/client/src/c_launchparameters.cpp @@ -50,6 +50,8 @@ static void LPARAM_fullbright(const std::vector &argv) { c_engine-> static void LPARAM_vk_enable_validation(const std::vector &argv) { c_engine->SetGfxAPIValidationEnabled(true); } +static void LPARAM_vk_enable_gfx_diagnostics(const std::vector &argv) { c_engine->SetGfxDiagnosticsModeEnabled(true); } + static void LPARAM_render_api(const std::vector &argv) { if(argv.empty()) @@ -138,6 +140,7 @@ REGISTER_LAUNCH_PARAMETER_HELP(-h, LPARAM_h, "", "set the screen height" REGISTER_LAUNCH_PARAMETER_HELP(-fullbright, LPARAM_fullbright, "", "start in fullbright mode"); REGISTER_LAUNCH_PARAMETER_HELP(-enable_gfx_validation, LPARAM_vk_enable_validation, "<1/0>", "Enables or disables graphics API validation."); +REGISTER_LAUNCH_PARAMETER_HELP(-enable_gfx_diagnostics, LPARAM_vk_enable_gfx_diagnostics, "<1/0>", "Enables or disables GPU diagnostics mode."); REGISTER_LAUNCH_PARAMETER_HELP(-graphics_api, LPARAM_render_api, "", "Changes the graphics API to use for rendering."); REGISTER_LAUNCH_PARAMETER_HELP(-audio_api, LPARAM_audio_api, "", "Changes the audio API to use for audio playback."); REGISTER_LAUNCH_PARAMETER_HELP(-auto_exec, LPARAM_auto_exec, "