diff --git a/README.md b/README.md index da014d8e2..b52b436cf 100644 --- a/README.md +++ b/README.md @@ -61,10 +61,13 @@ Build Requirements Build Instructions ------ -To build Pragma, all you have to do is run the following command from a command-line interface: +Quick-Start: Simply run the "build.bat" for Windows or "build.sh" for Linux systems to build Pragma with the default settings. + +Alternatively you can run the following command from a command-line interface: ```console git clone https://github.com/Silverlan/pragma.git && cd pragma && python build_scripts/build.py --with-pfm --with-all-pfm-modules --with-vr ``` +(Use `python3` instead of `python` if you're on Linux.) This will clone Pragma and run the build-script, which will automatically download all dependencies, configure CMake, and build and install the project (this will take several hours). If you don't need the filmmaker, you can omit the `--with-pfm --with-all-pfm-modules` arguments, which will reduce the build time and the required amount of disk space. 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..76efc0c7f --- /dev/null +++ b/assets/addons/shader_graph/lua/gui/shader_graph/node.lua @@ -0,0 +1,120 @@ +--[[ + 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) + box:AddCallback("SetSize", function() + self:SetHeight(box:GetBottom()) + end) + + local outputControls = gui.create("WIPFMControlsMenu", box, 0, 0, box:GetWidth(), box:GetHeight()) + outputControls:SetAutoFillContentsToHeight(false) + outputControls:SetFixedHeight(false) + self.m_outputControls = outputControls + + 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 + + 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, type) + local ctrlMenu = (socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT) and self.m_inputControls + or self.m_outputControls + local elCtrl + if socketType == gui.GraphNodeSocket.SOCKET_TYPE_INPUT and type ~= nil then + 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, "") + elCtrl = wrapper + end + 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, elCtrl +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, 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, 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 +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..f3cf9adda --- /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("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) + 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..d4539169f --- /dev/null +++ b/assets/addons/shader_graph/lua/gui/shader_graph/shader_graph.lua @@ -0,0 +1,289 @@ +--[[ + 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_nameToElementData = {} + self.m_nodeData = {} + self.m_linkElements = {} + self:Clear() + self:SetSize(1280, 1024) + + 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("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("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: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 + local frame = self:AddNode(graphNode) + frame:SetX(offset) + offset = offset + frame:GetWidth() + 80 + 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_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 + 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:SetZPos(-1) + 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 name = graphNode:GetName() + local frame = gui.create("WIFrame", self) + 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) + 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:SetY(31) + 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, socket.type) + end + + 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) + + local t = { + frame = frame, + nodeElement = elNode, + graphNode = name, + } + table.insert(self.m_nodeData, t) + self.m_nameToElementData[graphNode:GetName()] = t + return frame +end +gui.register("WIShaderGraph", Element) 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 + } + } + ] +} 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 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/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/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) { diff --git a/assets/shaders/math/math.glsl b/assets/shaders/math/math.glsl index e41d0a9e9..af871756b 100644 --- a/assets/shaders/math/math.glsl +++ b/assets/shaders/math/math.glsl @@ -24,11 +24,16 @@ #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; } 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 @@ -37,4 +42,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 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/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/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/image_texture.glsl b/assets/shaders/modules/image_texture.glsl new file mode 100644 index 000000000..e69de29bb 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/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/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/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/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" 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/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/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.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..." diff --git a/build_scripts/build.py b/build_scripts/build.py index 8e2378664..14067efce 100644 --- a/build_scripts/build.py +++ b/build_scripts/build.py @@ -187,10 +187,10 @@ if platform == "linux" and (c_compiler == "clang-19" or c_compiler == "clang++-19"): curDir = os.getcwd() os.chdir(deps_dir) - clang19_root = os.getcwd() +"/LLVM-19.1.2-Linux-X64" + clang19_root = os.getcwd() +"/LLVM-19.1.5-Linux-X64" if not Path(clang19_root).is_dir(): print_msg("Downloading clang-19...") - http_extract("https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.2/LLVM-19.1.2-Linux-X64.tar.xz",format="tar.xz") + http_extract("https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.5/LLVM-19.1.5-Linux-X64.tar.xz",format="tar.xz") if c_compiler == "clang-19": c_compiler = clang19_root +"/bin/clang" if cxx_compiler == "clang++-19": @@ -494,21 +494,21 @@ 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 ########## print_msg("Downloading SPIRV-Headers...") os.chdir(deps_dir) os.chdir("SPIRV-Tools/external") -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") +if not Path(os.getcwd() +"/spirv-headers").is_dir(): + git_clone("https://github.com/KhronosGroup/SPIRV-Headers", "spirv-headers") +os.chdir("spirv-headers") +reset_to_commit("2a9b6f951c7d6b04b6c21fe1bf3f475b68b84801") os.chdir("../../") os.chdir("../../") @@ -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="9071ef182a9286369922fab76232267208027a93", + commitSha="7a6fdd08d4ab4f0677d2c3f0223b99a18a8f2e33", repositoryUrl="https://github.com/Silverlan/pr_prosper_vulkan.git" ) @@ -842,7 +843,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") @@ -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 @@ -1136,8 +1141,8 @@ 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("model editor","tool_model_editor","https://github.com/Silverlan/pragma_model_editor.git","bd4844c06b9a42bacd17bb7e52d3381c3fd119e4") + 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: 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 1659cf021..05fee5e6c 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","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") @@ -32,8 +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("vfilesystem","https://github.com/Silverlan/vfilesystem.git","3d6001b2202ac4eecb8d68de1909f72c22060a31") -get_submodule("wgui","https://github.com/Silverlan/wgui.git","66d3758336d6e58046813a30298a6a3d9af74318") +get_submodule("util_shadergraph","https://github.com/Silverlan/util_shadergraph.git","c3f6ad2671633f2e7cddb55fdd2bc831927043c6") +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 25f6bd632..990ddc0bf 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_vulkan","https://github.com/Silverlan/pr_prosper_vulkan.git","9071ef182a9286369922fab76232267208027a93") +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","7a6fdd08d4ab4f0677d2c3f0223b99a18a8f2e33") os.chdir(curDir) 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) 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/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/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 b9a91daa3..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; @@ -202,7 +203,6 @@ namespace pragma { // rendering has finished. void SetFrameDepthBufferSamplingRequired(); - prosper::IDescriptorSet *GetLightSourceDescriptorSet() const; prosper::IDescriptorSet *GetLightSourceDescriptorSetCompute() const; prosper::Shader *GetWireframeShader() const; @@ -268,7 +268,6 @@ namespace pragma { LightMapInfo m_lightMapInfo = {}; bool m_bFrameDepthBufferSamplingRequired = false; - std::shared_ptr m_dsgLights; std::shared_ptr m_dsgLightsCompute; std::vector m_visLightSources; @@ -304,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/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/include/pragma/rendering/shader_graph/manager.hpp b/core/client/include/pragma/rendering/shader_graph/manager.hpp new file mode 100644 index 000000000..f846dcfb2 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/manager.hpp @@ -0,0 +1,76 @@ +/* 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; } + const std::string &GetTypeName() const { return m_typeName; } + const std::shared_ptr &GetGraph() const { return m_graph; } + 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 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(); + 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; + }; +} + +#endif 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..812791d34 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/module.hpp @@ -0,0 +1,53 @@ +/* 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" + +import pragma.shadergraph; + +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; + void SetNodes(std::vector &&nodes) { m_nodes = std::move(nodes); } + protected: + prosper::Shader &m_shader; + std::vector m_nodes; + }; + + 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, std::vector &&nodes) 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/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/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/camera.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp new file mode 100644 index 000000000..b6c1dd2df --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/camera.hpp @@ -0,0 +1,46 @@ +/* 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; + }; +}; + +#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/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/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/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/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/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/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/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/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/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/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 new file mode 100644 index 000000000..ac86283e3 --- /dev/null +++ b/core/client/include/pragma/rendering/shaders/world/c_shader_graph.hpp @@ -0,0 +1,41 @@ +/* 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 { + 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 &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override; + protected: + using ShaderGameWorldLightingPass::RecordDraw; + 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); + + std::shared_ptr m_defaultPbrDsg = nullptr; + std::vector> m_modules; + }; +}; + +#endif 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/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/c_engine.cpp b/core/client/src/c_engine.cpp index a592f9aa2..dd90cfa19 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[]) { @@ -90,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; @@ -103,14 +101,26 @@ 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" +#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 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"); @@ -182,6 +192,44 @@ CEngine::CEngine(int argc, char *argv[]) return wrapper; }); } + + { + 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("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); + 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); + + 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); }); + } } void CEngine::Release() @@ -260,35 +308,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) @@ -725,6 +768,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(); @@ -734,11 +778,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 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) { @@ -849,7 +993,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); @@ -997,9 +1141,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 { 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) { 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, "