Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert 3.x shaders
Browse files Browse the repository at this point in the history
nikitalita committed Oct 3, 2024
1 parent 6f36e92 commit 275104a
Showing 11 changed files with 4,252 additions and 11 deletions.
84 changes: 82 additions & 2 deletions editor/plugins/text_shader_editor.cpp
Original file line number Diff line number Diff line change
@@ -42,6 +42,10 @@
#include "servers/rendering/shader_preprocessor.h"
#include "servers/rendering/shader_types.h"

#ifndef DISABLE_DEPRECATED
#include "servers/rendering/shader_converter.h"
#endif

/*** SHADER SYNTAX HIGHLIGHTER ****/

Dictionary GDShaderSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
@@ -699,6 +703,28 @@ void TextShaderEditor::_menu_option(int p_option) {
case EDIT_COMPLETE: {
code_editor->get_text_editor()->request_code_completion();
} break;
#ifndef DISABLE_DEPRECATED
case EDIT_CONVERT: {
if (shader.is_null()) {
return;
}
String code = code_editor->get_text_editor()->get_text();
if (code.is_empty()) {
return;
}
ShaderDeprecatedConverter converter;
if (!converter.is_code_deprecated(code)) {
if (converter.get_error_text() != String()) {
shader_convert_error_dialog->set_text(vformat(RTR("Line %d: %s"), converter.get_error_line(), converter.get_error_text()));
shader_convert_error_dialog->popup_centered();
ERR_PRINT("Shader conversion failed: " + converter.get_error_text());
}
confirm_convert_shader->popup_centered();
return;
}
_convert_shader();
} break;
#endif
case SEARCH_FIND: {
code_editor->get_find_replace_bar()->popup_search();
} break;
@@ -755,6 +781,43 @@ void TextShaderEditor::_notification(int p_what) {
} break;
}
}
#ifndef DISABLE_DEPRECATED
void TextShaderEditor::_convert_shader() {
if (shader.is_null()) {
return;
}
String code = code_editor->get_text_editor()->get_text();
if (code.is_empty()) {
return;
}
ShaderDeprecatedConverter converter;
if (!converter.convert_code(code)) {
String err_text = converter.get_error_text();
if (err_text.is_empty()) {
err_text = TTR("Unknown error occurred while converting the shader.");
} else if (converter.get_error_line() > 0) {
err_text = vformat("%s (line %d)", err_text, converter.get_error_line());
}

shader_convert_error_dialog->set_text(err_text);
shader_convert_error_dialog->popup_centered();
ERR_PRINT("Shader conversion failed: " + err_text);
return;
}
String new_code = converter.emit_code();

#ifdef DEBUG_ENABLED
print_line(converter.get_report());
#endif
if (new_code == code) {
return;
}
// Ensure undoable.
code_editor->get_text_editor()->set_text(new_code);
code_editor->get_text_editor()->tag_saved_version();
code_editor->_validate_script();
}
#endif

void TextShaderEditor::_editor_settings_changed() {
if (!EditorThemeManager::is_generated_theme_outdated() &&
@@ -1170,8 +1233,12 @@ TextShaderEditor::TextShaderEditor() {
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_word_wrap"), EDIT_TOGGLE_WORD_WRAP);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE);
edit_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &TextShaderEditor::_menu_option));

#ifndef DISABLE_DEPRECATED
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_item(TTR("Convert 3.x Shader"), EDIT_CONVERT);
#endif
edit_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &TextShaderEditor::_menu_option));
search_menu = memnew(MenuButton);
search_menu->set_shortcut_context(this);
search_menu->set_text(TTR("Search"));
@@ -1254,7 +1321,20 @@ TextShaderEditor::TextShaderEditor() {
disk_changed->connect("custom_action", callable_mp(this, &TextShaderEditor::save_external_data));

add_child(disk_changed);

#ifndef DISABLE_DEPRECATED
shader_convert_error_dialog = memnew(AcceptDialog);
shader_convert_error_dialog->set_title(TTR("Error converting shader"));
shader_convert_error_dialog->set_hide_on_ok(true);
add_child(shader_convert_error_dialog);

confirm_convert_shader = memnew(ConfirmationDialog);
confirm_convert_shader->set_title(TTR("Confirm Convert 3.x Shader"));
confirm_convert_shader->set_text(TTR("This shader does not appear to be a 3.x shader.\nAre you sure you want to convert it?"));
confirm_convert_shader->get_ok_button()->set_text(TTR("Convert"));
confirm_convert_shader->get_cancel_button()->set_text(TTR("Cancel"));
confirm_convert_shader->connect("confirmed", callable_mp(this, &TextShaderEditor::_convert_shader));
add_child(confirm_convert_shader);
#endif
_editor_settings_changed();
code_editor->show_toggle_scripts_button(); // TODO: Disabled for now, because it doesn't work properly.
}
9 changes: 9 additions & 0 deletions editor/plugins/text_shader_editor.h
Original file line number Diff line number Diff line change
@@ -125,6 +125,7 @@ class TextShaderEditor : public ShaderEditor {
EDIT_TOGGLE_WORD_WRAP,
EDIT_TOGGLE_COMMENT,
EDIT_COMPLETE,
EDIT_CONVERT,
SEARCH_FIND,
SEARCH_FIND_NEXT,
SEARCH_FIND_PREV,
@@ -150,13 +151,21 @@ class TextShaderEditor : public ShaderEditor {
ConfirmationDialog *disk_changed = nullptr;

ShaderTextEditor *code_editor = nullptr;
#ifndef DISABLE_DEPRECATED
AcceptDialog *shader_convert_error_dialog = nullptr;
ConfirmationDialog *confirm_convert_shader = nullptr;
#endif

bool compilation_success = true;

void _menu_option(int p_option);
void _prepare_edit_menu();
mutable Ref<Shader> shader;
mutable Ref<ShaderInclude> shader_inc;

#ifndef DISABLE_DEPRECATED
void _convert_shader();
#endif
void _editor_settings_changed();
void _apply_editor_settings();
void _project_settings_changed();
69 changes: 68 additions & 1 deletion scene/resources/shader.cpp
Original file line number Diff line number Diff line change
@@ -32,8 +32,11 @@
#include "shader.compat.inc"

#include "core/io/file_access.h"
#include "scene/scene_string_names.h"
#include "servers/rendering/rendering_server_globals.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/shader_preprocessor.h"
#include "servers/rendering/shader_types.h"
#include "servers/rendering_server.h"
#include "texture.h"

@@ -46,6 +49,12 @@
#endif
#endif

#ifndef DISABLE_DEPRECATED
#include "servers/rendering/shader_converter.h"
#endif

#define _LOAD_COMPAT_META_PROPERTY "_load_compat"

Shader::Mode Shader::get_mode() const {
return mode;
}
@@ -81,13 +90,57 @@ void Shader::set_include_path(const String &p_path) {
include_path = p_path;
}

#ifndef DISABLE_DEPRECATED
ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_name) {
RS::GlobalShaderParameterType gvt = RenderingServerGlobals::material_storage->global_shader_parameter_get_type(p_name);
return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt);
}
#endif

void Shader::set_code(const String &p_code) {
for (const Ref<ShaderInclude> &E : include_dependencies) {
E->disconnect_changed(callable_mp(this, &Shader::_dependency_changed));
}

code = p_code;
preprocessed_code = p_code;
#ifndef DISABLE_DEPRECATED
if (get_meta(_LOAD_COMPAT_META_PROPERTY, false)) {
// check if the Shader code compiles; if not, it's probably an old shader.

ShaderLanguage sl;
ShaderLanguage::ShaderCompileInfo info;
String mode_string = ShaderLanguage::get_shader_type(p_code);

RS::ShaderMode new_mode;
if (mode_string == "canvas_item") {
new_mode = RS::SHADER_CANVAS_ITEM;
} else if (mode_string == "particles") {
new_mode = RS::SHADER_PARTICLES;
} else if (mode_string == "spatial") {
new_mode = RS::SHADER_SPATIAL;
} else {
new_mode = RS::SHADER_MAX;
}
if (new_mode != RS::SHADER_MAX) {
info.functions = ShaderTypes::get_singleton()->get_functions(new_mode);
info.render_modes = ShaderTypes::get_singleton()->get_modes(new_mode);
info.shader_types = ShaderTypes::get_singleton()->get_types();
info.global_shader_uniform_type_func = _get_global_shader_uniform_type;
Error err = sl.compile(p_code, info);
if (err) {
ShaderDeprecatedConverter sdc;
if (sdc.is_code_deprecated(p_code)) {
ERR_FAIL_COND_MSG(!sdc.convert_code(p_code), vformat("Shader conversion failed (line %d): %s", sdc.get_error_line(), sdc.get_error_text()));
code = sdc.emit_code();
preprocessed_code = code;
} else if (sdc.get_error_text() != "") { // Preprocessing failed.
WARN_PRINT(vformat("Shader conversion failed (line %d): %s", sdc.get_error_line(), sdc.get_error_text()));
} // 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.
}
}
}
#endif

{
String path = get_path();
@@ -99,7 +152,7 @@ void Shader::set_code(const String &p_code) {
// 2) Server does not do interaction with Resource filetypes, this is a scene level feature.
HashSet<Ref<ShaderInclude>> new_include_dependencies;
ShaderPreprocessor preprocessor;
Error result = preprocessor.preprocess(p_code, path, preprocessed_code, nullptr, nullptr, nullptr, &new_include_dependencies);
Error result = preprocessor.preprocess(code, path, preprocessed_code, nullptr, nullptr, nullptr, &new_include_dependencies);
if (result == OK) {
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
include_dependencies = new_include_dependencies;
@@ -256,6 +309,20 @@ Array Shader::_get_shader_uniform_list(bool p_get_groups) {
return ret;
}

void Shader::_start_load(const StringName &p_res_format_type, int p_res_format_version) {
#ifndef DISABLE_DEPRECATED
if ((p_res_format_type == "binary" && p_res_format_version == 3) || (p_res_format_type == "text" && p_res_format_version == 2)) {
set_meta(_LOAD_COMPAT_META_PROPERTY, true);
}
#endif
}

void Shader::_finish_load(const StringName &p_res_format_type, int p_res_format_version) {
#ifndef DISABLE_DEPRECATED
set_meta(_LOAD_COMPAT_META_PROPERTY, Variant());
#endif
}

void Shader::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mode"), &Shader::get_mode);

3 changes: 3 additions & 0 deletions scene/resources/shader.h
Original file line number Diff line number Diff line change
@@ -98,6 +98,9 @@ class Shader : public Resource {

virtual RID get_rid() const override;

virtual void _start_load(const StringName &p_res_format_type, int p_res_format_version) override;
virtual void _finish_load(const StringName &p_res_format_type, int p_res_format_version) override;

Shader();
~Shader();
};
Loading

0 comments on commit 275104a

Please sign in to comment.