diff options
-rw-r--r-- | editor/plugins/text_shader_editor.cpp | 5 | ||||
-rw-r--r-- | scene/resources/shader.cpp | 13 | ||||
-rw-r--r-- | scene/resources/shader.h | 2 | ||||
-rw-r--r-- | scene/resources/shader_include.cpp | 12 | ||||
-rw-r--r-- | scene/resources/shader_include.h | 3 | ||||
-rw-r--r-- | servers/rendering/shader_preprocessor.cpp | 5 |
6 files changed, 36 insertions, 4 deletions
diff --git a/editor/plugins/text_shader_editor.cpp b/editor/plugins/text_shader_editor.cpp index 1b29999796..ffd9564816 100644 --- a/editor/plugins/text_shader_editor.cpp +++ b/editor/plugins/text_shader_editor.cpp @@ -383,11 +383,12 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptLa List<ScriptLanguage::CodeCompletionOption> pp_defines; ShaderPreprocessor preprocessor; String code; - complete_from_path = (shader.is_valid() ? shader->get_path() : shader_inc->get_path()).get_base_dir(); + String resource_path = (shader.is_valid() ? shader->get_path() : shader_inc->get_path()); + complete_from_path = resource_path.get_base_dir(); if (!complete_from_path.ends_with("/")) { complete_from_path += "/"; } - preprocessor.preprocess(p_code, "", code, nullptr, nullptr, nullptr, nullptr, &pp_options, &pp_defines, _complete_include_paths); + preprocessor.preprocess(p_code, resource_path, code, nullptr, nullptr, nullptr, nullptr, &pp_options, &pp_defines, _complete_include_paths); complete_from_path = String(); if (pp_options.size()) { for (const ScriptLanguage::CodeCompletionOption &E : pp_options) { diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index a09dbd50cf..fd2be9ba22 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -55,6 +55,12 @@ void Shader::set_path(const String &p_path, bool p_take_over) { RS::get_singleton()->shader_set_path_hint(shader, p_path); } +void Shader::set_include_path(const String &p_path) { + // Used only if the shader does not have a resource path set, + // for example during loading stage or when created by code. + include_path = p_path; +} + void Shader::set_code(const String &p_code) { for (Ref<ShaderInclude> E : include_dependencies) { E->disconnect(SNAME("changed"), callable_mp(this, &Shader::_dependency_changed)); @@ -80,11 +86,15 @@ void Shader::set_code(const String &p_code) { HashSet<Ref<ShaderInclude>> new_include_dependencies; { + String path = get_path(); + if (path.is_empty()) { + path = include_path; + } // Preprocessor must run here and not in the server because: // 1) Need to keep track of include dependencies at resource level // 2) Server does not do interaction with Resource filetypes, this is a scene level feature. ShaderPreprocessor preprocessor; - preprocessor.preprocess(p_code, "", pp_code, nullptr, nullptr, nullptr, &new_include_dependencies); + preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_include_dependencies); } // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) @@ -231,6 +241,7 @@ Ref<Resource> ResourceFormatLoaderShader::load(const String &p_path, const Strin String str; str.parse_utf8((const char *)buffer.ptr(), buffer.size()); + shader->set_include_path(p_path); shader->set_code(str); if (r_error) { diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 55608b6c11..ca889940ef 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -56,6 +56,7 @@ private: Mode mode = MODE_SPATIAL; HashSet<Ref<ShaderInclude>> include_dependencies; String code; + String include_path; HashMap<StringName, HashMap<int, Ref<Texture2D>>> default_textures; @@ -72,6 +73,7 @@ public: virtual Mode get_mode() const; virtual void set_path(const String &p_path, bool p_take_over = false) override; + void set_include_path(const String &p_path); void set_code(const String &p_code); String get_code() const; diff --git a/scene/resources/shader_include.cpp b/scene/resources/shader_include.cpp index cd5e9861f7..68137cbec0 100644 --- a/scene/resources/shader_include.cpp +++ b/scene/resources/shader_include.cpp @@ -45,9 +45,14 @@ void ShaderInclude::set_code(const String &p_code) { } { + String path = get_path(); + if (path.is_empty()) { + path = include_path; + } + String pp_code; ShaderPreprocessor preprocessor; - preprocessor.preprocess(p_code, "", pp_code, nullptr, nullptr, nullptr, &new_dependencies); + preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_dependencies); } // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) @@ -64,6 +69,10 @@ String ShaderInclude::get_code() const { return code; } +void ShaderInclude::set_include_path(const String &p_path) { + include_path = p_path; +} + void ShaderInclude::_bind_methods() { ClassDB::bind_method(D_METHOD("set_code", "code"), &ShaderInclude::set_code); ClassDB::bind_method(D_METHOD("get_code"), &ShaderInclude::get_code); @@ -86,6 +95,7 @@ Ref<Resource> ResourceFormatLoaderShaderInclude::load(const String &p_path, cons String str; str.parse_utf8((const char *)buffer.ptr(), buffer.size()); + shader_inc->set_include_path(p_path); shader_inc->set_code(str); if (r_error) { diff --git a/scene/resources/shader_include.h b/scene/resources/shader_include.h index 04f4f5cf84..a8949b327e 100644 --- a/scene/resources/shader_include.h +++ b/scene/resources/shader_include.h @@ -42,6 +42,7 @@ class ShaderInclude : public Resource { private: String code; + String include_path; HashSet<Ref<ShaderInclude>> dependencies; void _dependency_changed(); @@ -51,6 +52,8 @@ protected: public: void set_code(const String &p_text); String get_code() const; + + void set_include_path(const String &p_path); }; class ResourceFormatLoaderShaderInclude : public ResourceFormatLoader { diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp index 816d937e9f..b45a7c0db3 100644 --- a/servers/rendering/shader_preprocessor.cpp +++ b/servers/rendering/shader_preprocessor.cpp @@ -674,6 +674,11 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) { return; } + path = path.simplify_path(); + if (path.is_relative_path()) { + path = state->current_filename.get_base_dir().path_join(path); + } + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { set_error(RTR("Shader include load failed. Does the shader include exist? Is there a cyclic dependency?"), line); |