You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-02 16:48:55 +00:00
Separate visual shader code out of shader editor plugin and dialog
This commit is contained in:
@@ -2711,17 +2711,17 @@ void FileSystemDock::_resource_created() {
|
|||||||
fpath = fpath.get_base_dir();
|
fpath = fpath.get_base_dir();
|
||||||
}
|
}
|
||||||
|
|
||||||
String type_name = new_resource_dialog->get_selected_type();
|
const String type_name = new_resource_dialog->get_selected_type();
|
||||||
if (type_name == "Shader") {
|
if (type_name == "Shader") {
|
||||||
make_shader_dialog->config(fpath.path_join("new_shader"), false, false, 0);
|
make_shader_dialog->config(fpath.path_join("new_shader"), false, false, type_name);
|
||||||
make_shader_dialog->popup_centered();
|
|
||||||
return;
|
|
||||||
} else if (type_name == "VisualShader") {
|
|
||||||
make_shader_dialog->config(fpath.path_join("new_shader"), false, false, 1);
|
|
||||||
make_shader_dialog->popup_centered();
|
make_shader_dialog->popup_centered();
|
||||||
return;
|
return;
|
||||||
} else if (type_name == "ShaderInclude") {
|
} else if (type_name == "ShaderInclude") {
|
||||||
make_shader_dialog->config(fpath.path_join("new_shader_include"), false, false, 2);
|
make_shader_dialog->config(fpath.path_join("new_shader_include"), false, false, type_name);
|
||||||
|
make_shader_dialog->popup_centered();
|
||||||
|
return;
|
||||||
|
} else if (type_name == "VisualShader") {
|
||||||
|
make_shader_dialog->config(fpath.path_join("new_shader"), false, false, type_name);
|
||||||
make_shader_dialog->popup_centered();
|
make_shader_dialog->popup_centered();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4255,7 +4255,7 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) {
|
|||||||
shader_create_dialog->connect("shader_created", callable_mp(this, &SceneTreeDock::_shader_created));
|
shader_create_dialog->connect("shader_created", callable_mp(this, &SceneTreeDock::_shader_created));
|
||||||
shader_create_dialog->connect(SceneStringName(confirmed), callable_mp(this, &SceneTreeDock::_shader_creation_closed));
|
shader_create_dialog->connect(SceneStringName(confirmed), callable_mp(this, &SceneTreeDock::_shader_creation_closed));
|
||||||
shader_create_dialog->connect("canceled", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
|
shader_create_dialog->connect("canceled", callable_mp(this, &SceneTreeDock::_shader_creation_closed));
|
||||||
shader_create_dialog->config(path, true, true, -1, p_preferred_mode);
|
shader_create_dialog->config(path, true, true, "", p_preferred_mode);
|
||||||
shader_create_dialog->popup_centered();
|
shader_create_dialog->popup_centered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
70
editor/shader/editor_shader_language_plugin.cpp
Normal file
70
editor/shader/editor_shader_language_plugin.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* editor_shader_language_plugin.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "editor_shader_language_plugin.h"
|
||||||
|
|
||||||
|
Vector<Ref<EditorShaderLanguagePlugin>> EditorShaderLanguagePlugin::shader_languages;
|
||||||
|
Vector<Vector2i> EditorShaderLanguagePlugin::language_variation_map;
|
||||||
|
|
||||||
|
void EditorShaderLanguagePlugin::register_shader_language(const Ref<EditorShaderLanguagePlugin> &p_shader_language) {
|
||||||
|
// Allows one ShaderLanguageEditorPlugin to provide multiple dropdown options in
|
||||||
|
// the language selection menu. For example, ShaderInclude is handled this way.
|
||||||
|
// X is the plugin index, and Y is the language variation index.
|
||||||
|
for (int i = 0; i < p_shader_language->get_language_variations().size(); i++) {
|
||||||
|
language_variation_map.push_back(Vector2i(shader_languages.size(), i));
|
||||||
|
}
|
||||||
|
shader_languages.push_back(p_shader_language);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorShaderLanguagePlugin::clear_registered_shader_languages() {
|
||||||
|
shader_languages.clear();
|
||||||
|
language_variation_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector<Ref<EditorShaderLanguagePlugin>> EditorShaderLanguagePlugin::get_shader_languages_read_only() {
|
||||||
|
return shader_languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EditorShaderLanguagePlugin::get_shader_language_variation_count() {
|
||||||
|
return language_variation_map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<EditorShaderLanguagePlugin> EditorShaderLanguagePlugin::get_shader_language_for_index(int p_index) {
|
||||||
|
ERR_FAIL_INDEX_V(p_index, language_variation_map.size(), nullptr);
|
||||||
|
Vector2i lang_var_indices = language_variation_map[p_index];
|
||||||
|
return shader_languages[lang_var_indices.x];
|
||||||
|
}
|
||||||
|
|
||||||
|
String EditorShaderLanguagePlugin::get_file_extension_for_index(int p_index) {
|
||||||
|
ERR_FAIL_INDEX_V(p_index, language_variation_map.size(), "tres");
|
||||||
|
Vector2i lang_var_indices = language_variation_map[p_index];
|
||||||
|
EditorShaderLanguagePlugin *lang = shader_languages[lang_var_indices.x].ptr();
|
||||||
|
return lang->get_file_extension(lang_var_indices.y);
|
||||||
|
}
|
||||||
57
editor/shader/editor_shader_language_plugin.h
Normal file
57
editor/shader/editor_shader_language_plugin.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* editor_shader_language_plugin.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#include "shader_editor.h"
|
||||||
|
|
||||||
|
class EditorShaderLanguagePlugin : public RefCounted {
|
||||||
|
GDCLASS(EditorShaderLanguagePlugin, RefCounted);
|
||||||
|
|
||||||
|
static Vector<Ref<EditorShaderLanguagePlugin>> shader_languages;
|
||||||
|
static Vector<Vector2i> language_variation_map;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void register_shader_language(const Ref<EditorShaderLanguagePlugin> &p_shader_language);
|
||||||
|
static void clear_registered_shader_languages();
|
||||||
|
static const Vector<Ref<EditorShaderLanguagePlugin>> get_shader_languages_read_only();
|
||||||
|
static int get_shader_language_variation_count();
|
||||||
|
static Ref<EditorShaderLanguagePlugin> get_shader_language_for_index(int p_index);
|
||||||
|
static String get_file_extension_for_index(int p_index);
|
||||||
|
|
||||||
|
virtual bool handles_shader(const Ref<Shader> &p_shader) const = 0;
|
||||||
|
virtual bool handles_shader_include(const Ref<ShaderInclude> &p_shader_inc) const { return false; }
|
||||||
|
virtual ShaderEditor *edit_shader(const Ref<Shader> &p_shader) = 0;
|
||||||
|
virtual ShaderEditor *edit_shader_include(const Ref<ShaderInclude> &p_shader_inc) { return nullptr; }
|
||||||
|
virtual Ref<Shader> create_new_shader(int p_variation_index, Shader::Mode p_shader_mode, int p_template_index) = 0;
|
||||||
|
virtual Ref<ShaderInclude> create_new_shader_include() { return Ref<ShaderInclude>(); }
|
||||||
|
virtual PackedStringArray get_language_variations() const = 0;
|
||||||
|
virtual String get_file_extension(int p_variation_index) const { return "tres"; }
|
||||||
|
};
|
||||||
@@ -34,41 +34,21 @@
|
|||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/gui/editor_file_dialog.h"
|
#include "editor/gui/editor_file_dialog.h"
|
||||||
#include "editor/gui/editor_validation_panel.h"
|
#include "editor/gui/editor_validation_panel.h"
|
||||||
|
#include "editor/shader/editor_shader_language_plugin.h"
|
||||||
#include "editor/themes/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/resources/shader_include.h"
|
#include "scene/resources/shader_include.h"
|
||||||
#include "scene/resources/visual_shader.h"
|
|
||||||
#include "servers/rendering/shader_types.h"
|
#include "servers/rendering/shader_types.h"
|
||||||
|
|
||||||
enum ShaderType {
|
|
||||||
SHADER_TYPE_TEXT,
|
|
||||||
SHADER_TYPE_VISUAL,
|
|
||||||
SHADER_TYPE_INC,
|
|
||||||
SHADER_TYPE_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
void ShaderCreateDialog::_notification(int p_what) {
|
void ShaderCreateDialog::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
String last_lang = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_language", "");
|
|
||||||
if (!last_lang.is_empty()) {
|
|
||||||
for (int i = 0; i < type_menu->get_item_count(); i++) {
|
|
||||||
if (type_menu->get_item_text(i) == last_lang) {
|
|
||||||
type_menu->select(i);
|
|
||||||
current_type = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
type_menu->select(default_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
current_mode = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_mode", 0);
|
current_mode = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_mode", 0);
|
||||||
mode_menu->select(current_mode);
|
mode_menu->select(current_mode);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case NOTIFICATION_THEME_CHANGED: {
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
_refresh_type_icons();
|
|
||||||
path_button->set_button_icon(get_editor_theme_icon(SNAME("Folder")));
|
path_button->set_button_icon(get_editor_theme_icon(SNAME("Folder")));
|
||||||
|
// Note that some of the theme logic happens in `config()` when opening the dialog.
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,16 +71,13 @@ void ShaderCreateDialog::_refresh_type_icons() {
|
|||||||
void ShaderCreateDialog::_update_language_info() {
|
void ShaderCreateDialog::_update_language_info() {
|
||||||
type_data.clear();
|
type_data.clear();
|
||||||
|
|
||||||
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
|
for (int i = 0; i < EditorShaderLanguagePlugin::get_shader_language_variation_count(); i++) {
|
||||||
ShaderTypeData shader_type_data;
|
ShaderTypeData shader_type_data;
|
||||||
if (i == int(SHADER_TYPE_TEXT)) {
|
if (i == 0) {
|
||||||
|
// HACK: The ShaderCreateDialog class currently only shows templates for text shaders. Generalize this later.
|
||||||
shader_type_data.use_templates = true;
|
shader_type_data.use_templates = true;
|
||||||
shader_type_data.default_extension = "gdshader";
|
|
||||||
} else if (i == int(SHADER_TYPE_INC)) {
|
|
||||||
shader_type_data.default_extension = "gdshaderinc";
|
|
||||||
} else {
|
|
||||||
shader_type_data.default_extension = "tres";
|
|
||||||
}
|
}
|
||||||
|
shader_type_data.default_extension = EditorShaderLanguagePlugin::get_file_extension_for_index(i);
|
||||||
shader_type_data.extensions.push_back(shader_type_data.default_extension);
|
shader_type_data.extensions.push_back(shader_type_data.default_extension);
|
||||||
if (shader_type_data.default_extension != "tres") {
|
if (shader_type_data.default_extension != "tres") {
|
||||||
shader_type_data.extensions.push_back("tres");
|
shader_type_data.extensions.push_back("tres");
|
||||||
@@ -155,93 +132,14 @@ void ShaderCreateDialog::_create_new() {
|
|||||||
Ref<Resource> shader;
|
Ref<Resource> shader;
|
||||||
Ref<Resource> shader_inc;
|
Ref<Resource> shader_inc;
|
||||||
|
|
||||||
switch (type_menu->get_selected()) {
|
const int type_index = type_menu->get_selected();
|
||||||
case SHADER_TYPE_TEXT: {
|
Ref<EditorShaderLanguagePlugin> shader_lang = EditorShaderLanguagePlugin::get_shader_language_for_index(type_index);
|
||||||
Ref<Shader> text_shader;
|
// A bit of an unfortunate hack because Shader and ShaderInclude do not share a common base class.
|
||||||
text_shader.instantiate();
|
// We need duplicate code paths for includes vs non-includes, so just check for the string "Include".
|
||||||
shader = text_shader;
|
if (type_menu->get_item_text(type_index).contains("Include")) {
|
||||||
|
shader_inc = shader_lang->create_new_shader_include();
|
||||||
StringBuilder code;
|
} else {
|
||||||
code += vformat("shader_type %s;\n", mode_menu->get_text().to_snake_case());
|
shader = shader_lang->create_new_shader(0, Shader::Mode(current_mode), current_template);
|
||||||
|
|
||||||
if (current_template == 0) { // Default template.
|
|
||||||
switch (current_mode) {
|
|
||||||
case Shader::MODE_SPATIAL:
|
|
||||||
code += R"(
|
|
||||||
void vertex() {
|
|
||||||
// Called for every vertex the material is visible on.
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
// Called for every pixel the material is visible on.
|
|
||||||
}
|
|
||||||
|
|
||||||
//void light() {
|
|
||||||
// // Called for every pixel for every light affecting the material.
|
|
||||||
// // Uncomment to replace the default light processing function with this one.
|
|
||||||
//}
|
|
||||||
)";
|
|
||||||
break;
|
|
||||||
case Shader::MODE_CANVAS_ITEM:
|
|
||||||
code += R"(
|
|
||||||
void vertex() {
|
|
||||||
// Called for every vertex the material is visible on.
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
// Called for every pixel the material is visible on.
|
|
||||||
}
|
|
||||||
|
|
||||||
//void light() {
|
|
||||||
// // Called for every pixel for every light affecting the CanvasItem.
|
|
||||||
// // Uncomment to replace the default light processing function with this one.
|
|
||||||
//}
|
|
||||||
)";
|
|
||||||
break;
|
|
||||||
case Shader::MODE_PARTICLES:
|
|
||||||
code += R"(
|
|
||||||
void start() {
|
|
||||||
// Called when a particle is spawned.
|
|
||||||
}
|
|
||||||
|
|
||||||
void process() {
|
|
||||||
// Called every frame on existing particles (according to the Fixed FPS property).
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
break;
|
|
||||||
case Shader::MODE_SKY:
|
|
||||||
code += R"(
|
|
||||||
void sky() {
|
|
||||||
// Called for every visible pixel in the sky background, as well as all pixels
|
|
||||||
// in the radiance cubemap.
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
break;
|
|
||||||
case Shader::MODE_FOG:
|
|
||||||
code += R"(
|
|
||||||
void fog() {
|
|
||||||
// Called once for every froxel that is touched by an axis-aligned bounding box
|
|
||||||
// of the associated FogVolume. This means that froxels that just barely touch
|
|
||||||
// a given FogVolume will still be used.
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text_shader->set_code(code.as_string());
|
|
||||||
} break;
|
|
||||||
case SHADER_TYPE_VISUAL: {
|
|
||||||
Ref<VisualShader> visual_shader;
|
|
||||||
visual_shader.instantiate();
|
|
||||||
shader = visual_shader;
|
|
||||||
visual_shader->set_mode(Shader::Mode(current_mode));
|
|
||||||
} break;
|
|
||||||
case SHADER_TYPE_INC: {
|
|
||||||
Ref<ShaderInclude> include;
|
|
||||||
include.instantiate();
|
|
||||||
shader_inc = include;
|
|
||||||
} break;
|
|
||||||
default: {
|
|
||||||
} break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader.is_null()) {
|
if (shader.is_null()) {
|
||||||
@@ -317,8 +215,18 @@ void ShaderCreateDialog::_type_changed(int p_language) {
|
|||||||
_path_changed(path);
|
_path_changed(path);
|
||||||
file_path->set_text(path);
|
file_path->set_text(path);
|
||||||
|
|
||||||
type_menu->set_item_disabled(int(SHADER_TYPE_INC), load_enabled);
|
mode_menu->set_disabled(false);
|
||||||
mode_menu->set_disabled(p_language == SHADER_TYPE_INC);
|
for (int i = 0; i < type_menu->get_item_count(); i++) {
|
||||||
|
const String item_name = type_menu->get_item_text(i);
|
||||||
|
if (item_name.contains("Include")) {
|
||||||
|
type_menu->set_item_disabled(i, load_enabled);
|
||||||
|
if (i == p_language) {
|
||||||
|
mode_menu->set_disabled(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type_menu->set_item_disabled(i, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
template_menu->set_disabled(!shader_type_data.use_templates);
|
template_menu->set_disabled(!shader_type_data.use_templates);
|
||||||
template_menu->clear();
|
template_menu->clear();
|
||||||
|
|
||||||
@@ -408,7 +316,43 @@ void ShaderCreateDialog::_path_submitted(const String &p_path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, int p_preferred_type, int p_preferred_mode) {
|
void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, const String &p_preferred_type, int p_preferred_mode) {
|
||||||
|
_update_language_info();
|
||||||
|
type_menu->clear();
|
||||||
|
const Vector<Ref<EditorShaderLanguagePlugin>> shader_langs = EditorShaderLanguagePlugin::get_shader_languages_read_only();
|
||||||
|
ERR_FAIL_COND_MSG(shader_langs.is_empty(), "ShaderCreateDialog: Unable to load any shader languages!");
|
||||||
|
for (Ref<EditorShaderLanguagePlugin> shader_lang : shader_langs) {
|
||||||
|
const PackedStringArray variations = shader_lang->get_language_variations();
|
||||||
|
for (const String &variation : variations) {
|
||||||
|
type_menu->add_item(variation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_refresh_type_icons();
|
||||||
|
|
||||||
|
int preferred_type = -1;
|
||||||
|
// Select preferred type if specified.
|
||||||
|
for (int i = 0; i < type_menu->get_item_count(); i++) {
|
||||||
|
if (type_menu->get_item_text(i) == p_preferred_type) {
|
||||||
|
preferred_type = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (preferred_type < 0 || preferred_type >= type_menu->get_item_count()) {
|
||||||
|
preferred_type = 0;
|
||||||
|
// Select the last selected language if possible, otherwise default to the first language.
|
||||||
|
String last_lang = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_language", "");
|
||||||
|
if (!last_lang.is_empty()) {
|
||||||
|
for (int i = 0; i < type_menu->get_item_count(); i++) {
|
||||||
|
if (type_menu->get_item_text(i) == last_lang) {
|
||||||
|
preferred_type = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type_menu->select(preferred_type);
|
||||||
|
current_type = 0;
|
||||||
|
|
||||||
if (!p_base_path.is_empty()) {
|
if (!p_base_path.is_empty()) {
|
||||||
initial_base_path = p_base_path.get_basename();
|
initial_base_path = p_base_path.get_basename();
|
||||||
file_path->set_text(initial_base_path + "." + type_data.get(type_menu->get_selected()).default_extension);
|
file_path->set_text(initial_base_path + "." + type_data.get(type_menu->get_selected()).default_extension);
|
||||||
@@ -426,11 +370,6 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl
|
|||||||
internal->set_pressed(EditorSettings::get_singleton()->get_project_metadata("shader_setup", "create_built_in_shader", false));
|
internal->set_pressed(EditorSettings::get_singleton()->get_project_metadata("shader_setup", "create_built_in_shader", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_preferred_type > -1) {
|
|
||||||
type_menu->select(p_preferred_type);
|
|
||||||
_type_changed(p_preferred_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_preferred_mode > -1) {
|
if (p_preferred_mode > -1) {
|
||||||
mode_menu->select(p_preferred_mode);
|
mode_menu->select(p_preferred_mode);
|
||||||
_mode_changed(p_preferred_mode);
|
_mode_changed(p_preferred_mode);
|
||||||
@@ -468,41 +407,14 @@ String ShaderCreateDialog::_validate_path(const String &p_path) {
|
|||||||
|
|
||||||
const ShaderCreateDialog::ShaderTypeData ¤t_type_data = type_data.get(current_type);
|
const ShaderCreateDialog::ShaderTypeData ¤t_type_data = type_data.get(current_type);
|
||||||
const String file_extension = stripped_file_path.get_extension();
|
const String file_extension = stripped_file_path.get_extension();
|
||||||
HashSet<String> extensions;
|
|
||||||
|
|
||||||
List<ShaderCreateDialog::ShaderTypeData>::ConstIterator itr = type_data.begin();
|
for (const String &type_ext : current_type_data.extensions) {
|
||||||
for (int i = 0; i < SHADER_TYPE_MAX; ++itr, ++i) {
|
if (type_ext.nocasecmp_to(file_extension) == 0) {
|
||||||
for (const String &ext : itr->extensions) {
|
return "";
|
||||||
if (!extensions.has(ext)) {
|
|
||||||
extensions.insert(ext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found = false;
|
return TTR("Invalid extension for selected shader type.");
|
||||||
bool match = false;
|
|
||||||
|
|
||||||
for (const String &ext : extensions) {
|
|
||||||
if (ext.nocasecmp_to(file_extension) == 0) {
|
|
||||||
found = true;
|
|
||||||
for (const String &type_ext : current_type_data.extensions) {
|
|
||||||
if (type_ext.nocasecmp_to(file_extension) == 0) {
|
|
||||||
match = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
return TTR("Invalid extension.");
|
|
||||||
}
|
|
||||||
if (!match) {
|
|
||||||
return TTR("Wrong extension chosen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderCreateDialog::_update_dialog() {
|
void ShaderCreateDialog::_update_dialog() {
|
||||||
@@ -598,36 +510,6 @@ ShaderCreateDialog::ShaderCreateDialog() {
|
|||||||
gc->add_child(memnew(Label(TTR("Type:"))));
|
gc->add_child(memnew(Label(TTR("Type:"))));
|
||||||
gc->add_child(type_menu);
|
gc->add_child(type_menu);
|
||||||
|
|
||||||
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
|
|
||||||
String type;
|
|
||||||
bool invalid = false;
|
|
||||||
switch (i) {
|
|
||||||
case SHADER_TYPE_TEXT:
|
|
||||||
type = "Shader";
|
|
||||||
default_type = i;
|
|
||||||
break;
|
|
||||||
case SHADER_TYPE_VISUAL:
|
|
||||||
type = "VisualShader";
|
|
||||||
break;
|
|
||||||
case SHADER_TYPE_INC:
|
|
||||||
type = "ShaderInclude";
|
|
||||||
break;
|
|
||||||
case SHADER_TYPE_MAX:
|
|
||||||
invalid = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
invalid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (invalid) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
type_menu->add_item(type);
|
|
||||||
}
|
|
||||||
if (default_type >= 0) {
|
|
||||||
type_menu->select(default_type);
|
|
||||||
}
|
|
||||||
current_type = default_type;
|
|
||||||
type_menu->connect(SceneStringName(item_selected), callable_mp(this, &ShaderCreateDialog::_type_changed));
|
type_menu->connect(SceneStringName(item_selected), callable_mp(this, &ShaderCreateDialog::_type_changed));
|
||||||
|
|
||||||
// Modes.
|
// Modes.
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ class ShaderCreateDialog : public ConfirmationDialog {
|
|||||||
bool load_enabled = false;
|
bool load_enabled = false;
|
||||||
bool re_check_path = false;
|
bool re_check_path = false;
|
||||||
int current_type = -1;
|
int current_type = -1;
|
||||||
int default_type = -1;
|
|
||||||
int current_mode = 0;
|
int current_mode = 0;
|
||||||
int current_template = 0;
|
int current_template = 0;
|
||||||
|
|
||||||
@@ -105,6 +104,6 @@ protected:
|
|||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true, int p_preferred_type = -1, int p_preferred_mode = -1);
|
void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true, const String &p_preferred_type = "", int p_preferred_mode = -1);
|
||||||
ShaderCreateDialog();
|
ShaderCreateDialog();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,7 +40,8 @@
|
|||||||
#include "editor/settings/editor_command_palette.h"
|
#include "editor/settings/editor_command_palette.h"
|
||||||
#include "editor/shader/shader_create_dialog.h"
|
#include "editor/shader/shader_create_dialog.h"
|
||||||
#include "editor/shader/text_shader_editor.h"
|
#include "editor/shader/text_shader_editor.h"
|
||||||
#include "editor/shader/visual_shader_editor_plugin.h"
|
#include "editor/shader/text_shader_language_plugin.h"
|
||||||
|
#include "editor/shader/visual_shader_language_plugin.h"
|
||||||
#include "editor/themes/editor_scale.h"
|
#include "editor/themes/editor_scale.h"
|
||||||
#include "scene/gui/item_list.h"
|
#include "scene/gui/item_list.h"
|
||||||
#include "scene/gui/tab_container.h"
|
#include "scene/gui/tab_container.h"
|
||||||
@@ -151,8 +152,12 @@ void ShaderEditorPlugin::edit(Object *p_object) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
es.shader_inc = Ref<ShaderInclude>(shader_include);
|
es.shader_inc = Ref<ShaderInclude>(shader_include);
|
||||||
es.shader_editor = memnew(TextShaderEditor);
|
for (Ref<EditorShaderLanguagePlugin> shader_lang : EditorShaderLanguagePlugin::get_shader_languages_read_only()) {
|
||||||
es.shader_editor->edit_shader_include(shader_include);
|
if (shader_lang->handles_shader_include(es.shader_inc)) {
|
||||||
|
es.shader_editor = shader_lang->edit_shader_include(es.shader_inc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If it's not a ShaderInclude, check for Shader.
|
// If it's not a ShaderInclude, check for Shader.
|
||||||
Shader *shader = Object::cast_to<Shader>(p_object);
|
Shader *shader = Object::cast_to<Shader>(p_object);
|
||||||
@@ -168,15 +173,15 @@ void ShaderEditorPlugin::edit(Object *p_object) {
|
|||||||
}
|
}
|
||||||
// If we did not return, the shader needs to be opened in a new shader editor.
|
// If we did not return, the shader needs to be opened in a new shader editor.
|
||||||
es.shader = Ref<Shader>(shader);
|
es.shader = Ref<Shader>(shader);
|
||||||
Ref<VisualShader> vs = es.shader;
|
for (Ref<EditorShaderLanguagePlugin> shader_lang : EditorShaderLanguagePlugin::get_shader_languages_read_only()) {
|
||||||
if (vs.is_valid()) {
|
if (shader_lang->handles_shader(es.shader)) {
|
||||||
es.shader_editor = memnew(VisualShaderEditor);
|
es.shader_editor = shader_lang->edit_shader(es.shader);
|
||||||
} else {
|
break;
|
||||||
es.shader_editor = memnew(TextShaderEditor);
|
}
|
||||||
}
|
}
|
||||||
es.shader_editor->edit_shader(es.shader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_NULL_MSG(es.shader_editor, "ShaderEditorPlugin: Unable to edit shader because no suitable editor was found.");
|
||||||
// TextShaderEditor-specific setup code.
|
// TextShaderEditor-specific setup code.
|
||||||
TextShaderEditor *text_shader_editor = Object::cast_to<TextShaderEditor>(es.shader_editor);
|
TextShaderEditor *text_shader_editor = Object::cast_to<TextShaderEditor>(es.shader_editor);
|
||||||
if (text_shader_editor) {
|
if (text_shader_editor) {
|
||||||
@@ -511,12 +516,12 @@ void ShaderEditorPlugin::_menu_item_pressed(int p_index) {
|
|||||||
switch (p_index) {
|
switch (p_index) {
|
||||||
case FILE_MENU_NEW: {
|
case FILE_MENU_NEW: {
|
||||||
String base_path = FileSystemDock::get_singleton()->get_current_path().get_base_dir();
|
String base_path = FileSystemDock::get_singleton()->get_current_path().get_base_dir();
|
||||||
shader_create_dialog->config(base_path.path_join("new_shader"), false, false, 0);
|
shader_create_dialog->config(base_path.path_join("new_shader"), false, false, "Shader");
|
||||||
shader_create_dialog->popup_centered();
|
shader_create_dialog->popup_centered();
|
||||||
} break;
|
} break;
|
||||||
case FILE_MENU_NEW_INCLUDE: {
|
case FILE_MENU_NEW_INCLUDE: {
|
||||||
String base_path = FileSystemDock::get_singleton()->get_current_path().get_base_dir();
|
String base_path = FileSystemDock::get_singleton()->get_current_path().get_base_dir();
|
||||||
shader_create_dialog->config(base_path.path_join("new_shader"), false, false, 2);
|
shader_create_dialog->config(base_path.path_join("new_shader"), false, false, "ShaderInclude");
|
||||||
shader_create_dialog->popup_centered();
|
shader_create_dialog->popup_centered();
|
||||||
} break;
|
} break;
|
||||||
case FILE_MENU_OPEN: {
|
case FILE_MENU_OPEN: {
|
||||||
@@ -927,9 +932,18 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
|
|||||||
files_split->add_child(shader_create_dialog);
|
files_split->add_child(shader_create_dialog);
|
||||||
shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created));
|
shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created));
|
||||||
shader_create_dialog->connect("shader_include_created", callable_mp(this, &ShaderEditorPlugin::_shader_include_created));
|
shader_create_dialog->connect("shader_include_created", callable_mp(this, &ShaderEditorPlugin::_shader_include_created));
|
||||||
|
|
||||||
|
Ref<TextShaderLanguagePlugin> text_shader_lang;
|
||||||
|
text_shader_lang.instantiate();
|
||||||
|
EditorShaderLanguagePlugin::register_shader_language(text_shader_lang);
|
||||||
|
|
||||||
|
Ref<VisualShaderLanguagePlugin> visual_shader_lang;
|
||||||
|
visual_shader_lang.instantiate();
|
||||||
|
EditorShaderLanguagePlugin::register_shader_language(visual_shader_lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderEditorPlugin::~ShaderEditorPlugin() {
|
ShaderEditorPlugin::~ShaderEditorPlugin() {
|
||||||
|
EditorShaderLanguagePlugin::clear_registered_shader_languages();
|
||||||
memdelete(file_menu);
|
memdelete(file_menu);
|
||||||
memdelete(make_floating);
|
memdelete(make_floating);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ class MenuButton;
|
|||||||
class ShaderCreateDialog;
|
class ShaderCreateDialog;
|
||||||
class ShaderEditor;
|
class ShaderEditor;
|
||||||
class TabContainer;
|
class TabContainer;
|
||||||
class TextShaderEditor;
|
|
||||||
class VBoxContainer;
|
class VBoxContainer;
|
||||||
class HBoxContainer;
|
class HBoxContainer;
|
||||||
class VisualShaderEditor;
|
|
||||||
class WindowWrapper;
|
class WindowWrapper;
|
||||||
|
|
||||||
class ShaderEditorPlugin : public EditorPlugin {
|
class ShaderEditorPlugin : public EditorPlugin {
|
||||||
|
|||||||
156
editor/shader/text_shader_language_plugin.cpp
Normal file
156
editor/shader/text_shader_language_plugin.cpp
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* text_shader_language_plugin.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "text_shader_language_plugin.h"
|
||||||
|
|
||||||
|
#include "text_shader_editor.h"
|
||||||
|
|
||||||
|
#include "core/string/string_builder.h"
|
||||||
|
#include "servers/rendering/shader_types.h"
|
||||||
|
|
||||||
|
bool TextShaderLanguagePlugin::handles_shader(const Ref<Shader> &p_shader) const {
|
||||||
|
// The text shader editor only edits the base Shader class,
|
||||||
|
// not classes that inherit from it like VisualShader.
|
||||||
|
return p_shader->get_class_name() == Shader::get_class_static();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextShaderLanguagePlugin::handles_shader_include(const Ref<ShaderInclude> &p_shader_inc) const {
|
||||||
|
return p_shader_inc->get_class_static() == ShaderInclude::get_class_static();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEditor *TextShaderLanguagePlugin::edit_shader(const Ref<Shader> &p_shader) {
|
||||||
|
TextShaderEditor *editor = memnew(TextShaderEditor);
|
||||||
|
editor->edit_shader(p_shader);
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEditor *TextShaderLanguagePlugin::edit_shader_include(const Ref<ShaderInclude> &p_shader_inc) {
|
||||||
|
TextShaderEditor *editor = memnew(TextShaderEditor);
|
||||||
|
editor->edit_shader_include(p_shader_inc);
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Shader> TextShaderLanguagePlugin::create_new_shader(int p_variation_index, Shader::Mode p_shader_mode, int p_template_index) {
|
||||||
|
Ref<Shader> shader;
|
||||||
|
shader.instantiate();
|
||||||
|
|
||||||
|
StringBuilder code;
|
||||||
|
const String &shader_type = ShaderTypes::get_singleton()->get_types_list().get(p_shader_mode);
|
||||||
|
code += vformat("shader_type %s;\n", shader_type);
|
||||||
|
|
||||||
|
if (p_template_index == 0) { // Default template.
|
||||||
|
switch (p_shader_mode) {
|
||||||
|
case Shader::MODE_SPATIAL: {
|
||||||
|
code += R"(
|
||||||
|
void vertex() {
|
||||||
|
// Called for every vertex the material is visible on.
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
// Called for every pixel the material is visible on.
|
||||||
|
}
|
||||||
|
|
||||||
|
//void light() {
|
||||||
|
// // Called for every pixel for every light affecting the material.
|
||||||
|
// // Uncomment to replace the default light processing function with this one.
|
||||||
|
//}
|
||||||
|
)";
|
||||||
|
} break;
|
||||||
|
case Shader::MODE_CANVAS_ITEM: {
|
||||||
|
code += R"(
|
||||||
|
void vertex() {
|
||||||
|
// Called for every vertex the material is visible on.
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
// Called for every pixel the material is visible on.
|
||||||
|
}
|
||||||
|
|
||||||
|
//void light() {
|
||||||
|
// // Called for every pixel for every light affecting the CanvasItem.
|
||||||
|
// // Uncomment to replace the default light processing function with this one.
|
||||||
|
//}
|
||||||
|
)";
|
||||||
|
} break;
|
||||||
|
case Shader::MODE_PARTICLES: {
|
||||||
|
code += R"(
|
||||||
|
void start() {
|
||||||
|
// Called when a particle is spawned.
|
||||||
|
}
|
||||||
|
|
||||||
|
void process() {
|
||||||
|
// Called every frame on existing particles (according to the Fixed FPS property).
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
} break;
|
||||||
|
case Shader::MODE_SKY: {
|
||||||
|
code += R"(
|
||||||
|
void sky() {
|
||||||
|
// Called for every visible pixel in the sky background, as well as all pixels
|
||||||
|
// in the radiance cubemap.
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
} break;
|
||||||
|
case Shader::MODE_FOG: {
|
||||||
|
code += R"(
|
||||||
|
void fog() {
|
||||||
|
// Called once for every froxel that is touched by an axis-aligned bounding box
|
||||||
|
// of the associated FogVolume. This means that froxels that just barely touch
|
||||||
|
// a given FogVolume will still be used.
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
} break;
|
||||||
|
case Shader::MODE_MAX: {
|
||||||
|
ERR_FAIL_V_MSG(Ref<Shader>(), "Invalid shader mode for text shader editor.");
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shader->set_code(code.as_string());
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<ShaderInclude> TextShaderLanguagePlugin::create_new_shader_include() {
|
||||||
|
Ref<ShaderInclude> shader_inc;
|
||||||
|
shader_inc.instantiate();
|
||||||
|
return shader_inc;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedStringArray TextShaderLanguagePlugin::get_language_variations() const {
|
||||||
|
return PackedStringArray{ "Shader", "ShaderInclude" };
|
||||||
|
}
|
||||||
|
|
||||||
|
String TextShaderLanguagePlugin::get_file_extension(int p_variation_index) const {
|
||||||
|
if (p_variation_index == 0) {
|
||||||
|
return "gdshader";
|
||||||
|
} else if (p_variation_index == 1) {
|
||||||
|
return "gdshaderinc";
|
||||||
|
}
|
||||||
|
return "tres";
|
||||||
|
}
|
||||||
47
editor/shader/text_shader_language_plugin.h
Normal file
47
editor/shader/text_shader_language_plugin.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* text_shader_language_plugin.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#include "editor/shader/editor_shader_language_plugin.h"
|
||||||
|
|
||||||
|
class TextShaderLanguagePlugin : public EditorShaderLanguagePlugin {
|
||||||
|
GDCLASS(TextShaderLanguagePlugin, EditorShaderLanguagePlugin);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool handles_shader(const Ref<Shader> &p_shader) const override;
|
||||||
|
virtual bool handles_shader_include(const Ref<ShaderInclude> &p_shader_inc) const override;
|
||||||
|
virtual ShaderEditor *edit_shader(const Ref<Shader> &p_shader) override;
|
||||||
|
virtual ShaderEditor *edit_shader_include(const Ref<ShaderInclude> &p_shader_inc) override;
|
||||||
|
virtual Ref<Shader> create_new_shader(int p_variation_index, Shader::Mode p_shader_mode, int p_template_index) override;
|
||||||
|
virtual Ref<ShaderInclude> create_new_shader_include() override;
|
||||||
|
virtual PackedStringArray get_language_variations() const override;
|
||||||
|
virtual String get_file_extension(int p_variation_index) const override;
|
||||||
|
};
|
||||||
58
editor/shader/visual_shader_language_plugin.cpp
Normal file
58
editor/shader/visual_shader_language_plugin.cpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* visual_shader_language_plugin.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#include "visual_shader_language_plugin.h"
|
||||||
|
|
||||||
|
#include "visual_shader_editor_plugin.h"
|
||||||
|
|
||||||
|
bool VisualShaderLanguagePlugin::handles_shader(const Ref<Shader> &p_shader) const {
|
||||||
|
return Object::cast_to<VisualShader>(p_shader.ptr()) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEditor *VisualShaderLanguagePlugin::edit_shader(const Ref<Shader> &p_shader) {
|
||||||
|
const Ref<VisualShader> shader = p_shader;
|
||||||
|
ERR_FAIL_COND_V(shader.is_null(), nullptr);
|
||||||
|
VisualShaderEditor *editor = memnew(VisualShaderEditor);
|
||||||
|
editor->edit_shader(shader);
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Shader> VisualShaderLanguagePlugin::create_new_shader(int p_variation_index, Shader::Mode p_shader_mode, int p_template_index) {
|
||||||
|
Ref<VisualShader> shader;
|
||||||
|
shader.instantiate();
|
||||||
|
shader->set_mode(p_shader_mode);
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedStringArray VisualShaderLanguagePlugin::get_language_variations() const {
|
||||||
|
PackedStringArray variations;
|
||||||
|
variations.push_back("VisualShader");
|
||||||
|
return variations;
|
||||||
|
}
|
||||||
43
editor/shader/visual_shader_language_plugin.h
Normal file
43
editor/shader/visual_shader_language_plugin.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* visual_shader_language_plugin.h */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* This file is part of: */
|
||||||
|
/* GODOT ENGINE */
|
||||||
|
/* https://godotengine.org */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||||
|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||||
|
/* */
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#include "editor/shader/editor_shader_language_plugin.h"
|
||||||
|
|
||||||
|
class VisualShaderLanguagePlugin : public EditorShaderLanguagePlugin {
|
||||||
|
GDCLASS(VisualShaderLanguagePlugin, EditorShaderLanguagePlugin);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool handles_shader(const Ref<Shader> &p_shader) const override;
|
||||||
|
virtual ShaderEditor *edit_shader(const Ref<Shader> &p_shader) override;
|
||||||
|
virtual Ref<Shader> create_new_shader(int p_variation_index, Shader::Mode p_shader_mode, int p_template_index) override;
|
||||||
|
virtual PackedStringArray get_language_variations() const override;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user