3838#include " scene/main/scene_tree.h"
3939#include " scene/resources/texture.h"
4040#include " servers/rendering/rendering_server.h"
41+ #include " servers/rendering/rendering_server_globals.h"
4142#include " servers/rendering/shader_language.h"
4243#include " servers/rendering/shader_preprocessor.h"
44+ #include " servers/rendering/shader_types.h"
4345
4446#ifdef TOOLS_ENABLED
4547#include " editor/doc/editor_help.h"
5052#endif
5153#endif
5254
55+ #ifndef DISABLE_DEPRECATED
56+ #include " servers/rendering/shader_converter.h"
57+ #endif
58+
59+ #define _LOAD_COMPAT_META_PROPERTY " _load_compat"
60+
5361Shader::Mode Shader::get_mode () const {
5462 return mode;
5563}
@@ -85,13 +93,57 @@ void Shader::set_include_path(const String &p_path) {
8593 include_path = p_path;
8694}
8795
96+ #ifndef DISABLE_DEPRECATED
97+ ShaderLanguage::DataType _get_global_shader_uniform_type (const StringName &p_name) {
98+ RenderingServerEnums::GlobalShaderParameterType gvt = RenderingServerGlobals::material_storage->global_shader_parameter_get_type (p_name);
99+ return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype (gvt);
100+ }
101+ #endif
102+
88103void Shader::set_code (const String &p_code) {
89104 for (const Ref<ShaderInclude> &E : include_dependencies) {
90105 E->disconnect_changed (callable_mp (this , &Shader::_dependency_changed));
91106 }
92107
93108 code = p_code;
94109 preprocessed_code = p_code;
110+ #ifndef DISABLE_DEPRECATED
111+ if (get_meta (_LOAD_COMPAT_META_PROPERTY, false )) {
112+ // check if the Shader code compiles; if not, it's probably an old shader.
113+
114+ ShaderLanguage sl;
115+ ShaderLanguage::ShaderCompileInfo info;
116+ String mode_string = ShaderLanguage::get_shader_type (p_code);
117+
118+ RenderingServerEnums::ShaderMode new_mode;
119+ if (mode_string == " canvas_item" ) {
120+ new_mode = RenderingServerEnums::SHADER_CANVAS_ITEM ;
121+ } else if (mode_string == " particles" ) {
122+ new_mode = RenderingServerEnums::SHADER_PARTICLES ;
123+ } else if (mode_string == " spatial" ) {
124+ new_mode = RenderingServerEnums::SHADER_SPATIAL ;
125+ } else {
126+ new_mode = RenderingServerEnums::SHADER_MAX ;
127+ }
128+ if (new_mode != RenderingServerEnums::SHADER_MAX ) {
129+ info.functions = ShaderTypes::get_singleton ()->get_functions (new_mode);
130+ info.render_modes = ShaderTypes::get_singleton ()->get_modes (new_mode);
131+ info.shader_types = ShaderTypes::get_singleton ()->get_types ();
132+ info.global_shader_uniform_type_func = _get_global_shader_uniform_type;
133+ Error err = sl.compile (p_code, info);
134+ if (err) {
135+ ShaderDeprecatedConverter sdc;
136+ if (sdc.is_code_deprecated (p_code)) {
137+ ERR_FAIL_COND_MSG (!sdc.convert_code (p_code), vformat (" Shader conversion failed (line %d): %s" , sdc.get_error_line (), sdc.get_error_text ()));
138+ code = sdc.emit_code ();
139+ preprocessed_code = code;
140+ } else if (sdc.get_error_text () != " " ) { // Preprocessing failed.
141+ WARN_PRINT (vformat (" Shader conversion failed (line %d): %s" , sdc.get_error_line (), sdc.get_error_text ()));
142+ } // If the code is reported as not deprecated, let it fall through to the compile step after this if block so that we get the full compile error.
143+ }
144+ }
145+ }
146+ #endif
95147
96148 {
97149 String path = get_path ();
@@ -103,7 +155,7 @@ void Shader::set_code(const String &p_code) {
103155 // 2) Server does not do interaction with Resource filetypes, this is a scene level feature.
104156 HashSet<Ref<ShaderInclude>> new_include_dependencies;
105157 ShaderPreprocessor preprocessor;
106- Error result = preprocessor.preprocess (p_code , path, preprocessed_code, nullptr , nullptr , nullptr , &new_include_dependencies);
158+ Error result = preprocessor.preprocess (code , path, preprocessed_code, nullptr , nullptr , nullptr , &new_include_dependencies);
107159 if (result == OK ) {
108160 // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
109161 include_dependencies = new_include_dependencies;
@@ -274,6 +326,20 @@ Array Shader::_get_shader_uniform_list(bool p_get_groups) {
274326 return ret;
275327}
276328
329+ void Shader::_start_load (const StringName &p_res_format_type, int p_res_format_version) {
330+ #ifndef DISABLE_DEPRECATED
331+ if ((p_res_format_type == " binary" && p_res_format_version == 3 ) || (p_res_format_type == " text" && p_res_format_version == 2 )) {
332+ set_meta (_LOAD_COMPAT_META_PROPERTY, true );
333+ }
334+ #endif
335+ }
336+
337+ void Shader::_finish_load (const StringName &p_res_format_type, int p_res_format_version) {
338+ #ifndef DISABLE_DEPRECATED
339+ set_meta (_LOAD_COMPAT_META_PROPERTY, Variant ());
340+ #endif
341+ }
342+
277343void Shader::_bind_methods () {
278344 ClassDB::bind_method (D_METHOD (" get_mode" ), &Shader::get_mode);
279345
@@ -329,9 +395,22 @@ Ref<Resource> ResourceFormatLoaderShader::load(const String &p_path, const Strin
329395 Ref<Shader> shader;
330396 shader.instantiate ();
331397
398+ #ifndef DISABLE_DEPRECATED
399+ bool is_deprecated = p_path.get_extension ().to_lower () == " shader" ;
400+ if (is_deprecated) {
401+ shader->set_meta (_LOAD_COMPAT_META_PROPERTY, true );
402+ }
403+ #endif
404+
332405 shader->set_include_path (p_path);
333406 shader->set_code (str);
334407
408+ #ifndef DISABLE_DEPRECATED
409+ if (is_deprecated) {
410+ shader->set_meta (_LOAD_COMPAT_META_PROPERTY, Variant ());
411+ }
412+ #endif
413+
335414 if (r_error) {
336415 *r_error = OK ;
337416 }
@@ -340,6 +419,9 @@ Ref<Resource> ResourceFormatLoaderShader::load(const String &p_path, const Strin
340419}
341420
342421void ResourceFormatLoaderShader::get_recognized_extensions (List<String> *p_extensions) const {
422+ #ifndef DISABLE_DEPRECATED
423+ p_extensions->push_back (" shader" );
424+ #endif
343425 p_extensions->push_back (" gdshader" );
344426}
345427
@@ -351,6 +433,11 @@ String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const
351433 if (p_path.has_extension (" gdshader" )) {
352434 return " Shader" ;
353435 }
436+ #ifndef DISABLE_DEPRECATED
437+ if (p_path.has_extension (" shader" )) {
438+ return " Shader" ;
439+ }
440+ #endif
354441 return " " ;
355442}
356443
0 commit comments