Merge pull request #61459 from reduz/new-shader-editor
This commit is contained in:
commit
b4804a2d3f
|
@ -7054,7 +7054,6 @@ EditorNode::EditorNode() {
|
||||||
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
|
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
|
||||||
add_editor_plugin(memnew(ShaderEditorPlugin));
|
add_editor_plugin(memnew(ShaderEditorPlugin));
|
||||||
add_editor_plugin(memnew(ShaderFileEditorPlugin));
|
add_editor_plugin(memnew(ShaderFileEditorPlugin));
|
||||||
add_editor_plugin(memnew(VisualShaderEditorPlugin));
|
|
||||||
|
|
||||||
add_editor_plugin(memnew(Camera3DEditorPlugin));
|
add_editor_plugin(memnew(Camera3DEditorPlugin));
|
||||||
add_editor_plugin(memnew(ThemeEditorPlugin));
|
add_editor_plugin(memnew(ThemeEditorPlugin));
|
||||||
|
|
|
@ -3547,7 +3547,7 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb
|
||||||
ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
|
ShaderEditorPlugin *shader_editor = Object::cast_to<ShaderEditorPlugin>(EditorNode::get_singleton()->get_editor_data().get_editor("Shader"));
|
||||||
shader_editor->edit(res.ptr());
|
shader_editor->edit(res.ptr());
|
||||||
shader_editor->make_visible(true);
|
shader_editor->make_visible(true);
|
||||||
shader_editor->get_shader_editor()->goto_line_selection(line_number - 1, begin, end);
|
shader_editor->get_shader_editor(res)->goto_line_selection(line_number - 1, begin, end);
|
||||||
return;
|
return;
|
||||||
} else if (fpath.get_extension() == "tscn") {
|
} else if (fpath.get_extension() == "tscn") {
|
||||||
EditorNode::get_singleton()->load_scene(fpath);
|
EditorNode::get_singleton()->load_scene(fpath);
|
||||||
|
|
|
@ -38,8 +38,12 @@
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_scale.h"
|
#include "editor/editor_scale.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
|
#include "editor/filesystem_dock.h"
|
||||||
|
#include "editor/plugins/visual_shader_editor_plugin.h"
|
||||||
#include "editor/project_settings_editor.h"
|
#include "editor/project_settings_editor.h"
|
||||||
#include "editor/property_editor.h"
|
#include "editor/property_editor.h"
|
||||||
|
#include "editor/shader_create_dialog.h"
|
||||||
|
#include "scene/gui/split_container.h"
|
||||||
#include "servers/display_server.h"
|
#include "servers/display_server.h"
|
||||||
#include "servers/rendering/shader_types.h"
|
#include "servers/rendering/shader_types.h"
|
||||||
|
|
||||||
|
@ -836,50 +840,216 @@ ShaderEditor::ShaderEditor() {
|
||||||
_editor_settings_changed();
|
_editor_settings_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderEditorPlugin::_update_shader_list() {
|
||||||
|
shader_list->clear();
|
||||||
|
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
|
||||||
|
String text;
|
||||||
|
String path = edited_shaders[i].shader->get_path();
|
||||||
|
String _class = edited_shaders[i].shader->get_class();
|
||||||
|
|
||||||
|
if (path.is_resource_file()) {
|
||||||
|
text = path.get_file();
|
||||||
|
} else if (edited_shaders[i].shader->get_name() != "") {
|
||||||
|
text = edited_shaders[i].shader->get_name();
|
||||||
|
} else {
|
||||||
|
text = _class + ":" + itos(edited_shaders[i].shader->get_instance_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shader_list->has_theme_icon(_class, SNAME("EditorIcons"))) {
|
||||||
|
_class = "Resource";
|
||||||
|
}
|
||||||
|
Ref<Texture2D> icon = shader_list->get_theme_icon(_class, SNAME("EditorIcons"));
|
||||||
|
|
||||||
|
shader_list->add_item(text, icon);
|
||||||
|
shader_list->set_item_tooltip(shader_list->get_item_count() - 1, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader_tabs->get_tab_count()) {
|
||||||
|
shader_list->select(shader_tabs->get_current_tab());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < FILE_MAX; i++) {
|
||||||
|
file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), edited_shaders.size() == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderEditorPlugin::edit(Object *p_object) {
|
void ShaderEditorPlugin::edit(Object *p_object) {
|
||||||
Shader *s = Object::cast_to<Shader>(p_object);
|
Shader *s = Object::cast_to<Shader>(p_object);
|
||||||
shader_editor->edit(s);
|
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
|
||||||
|
if (edited_shaders[i].shader.ptr() == s) {
|
||||||
|
// Exists, select.
|
||||||
|
shader_tabs->set_current_tab(i);
|
||||||
|
shader_list->select(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add.
|
||||||
|
EditedShader es;
|
||||||
|
es.shader = Ref<Shader>(s);
|
||||||
|
Ref<VisualShader> vs = es.shader;
|
||||||
|
if (vs.is_valid()) {
|
||||||
|
es.visual_shader_editor = memnew(VisualShaderEditor);
|
||||||
|
es.visual_shader_editor->edit(vs.ptr());
|
||||||
|
shader_tabs->add_child(es.visual_shader_editor);
|
||||||
|
} else {
|
||||||
|
es.shader_editor = memnew(ShaderEditor);
|
||||||
|
es.shader_editor->edit(s);
|
||||||
|
shader_tabs->add_child(es.shader_editor);
|
||||||
|
}
|
||||||
|
shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1);
|
||||||
|
edited_shaders.push_back(es);
|
||||||
|
_update_shader_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderEditorPlugin::handles(Object *p_object) const {
|
bool ShaderEditorPlugin::handles(Object *p_object) const {
|
||||||
Shader *shader = Object::cast_to<Shader>(p_object);
|
return Object::cast_to<Shader>(p_object) != nullptr;
|
||||||
return shader != nullptr && shader->is_text_shader();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderEditorPlugin::make_visible(bool p_visible) {
|
void ShaderEditorPlugin::make_visible(bool p_visible) {
|
||||||
if (p_visible) {
|
if (p_visible) {
|
||||||
button->show();
|
EditorNode::get_singleton()->make_bottom_panel_item_visible(main_split);
|
||||||
EditorNode::get_singleton()->make_bottom_panel_item_visible(shader_editor);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
button->hide();
|
|
||||||
if (shader_editor->is_visible_in_tree()) {
|
|
||||||
EditorNode::get_singleton()->hide_bottom_panel();
|
|
||||||
}
|
|
||||||
shader_editor->apply_shaders();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderEditorPlugin::selected_notify() {
|
void ShaderEditorPlugin::selected_notify() {
|
||||||
shader_editor->ensure_select_current();
|
}
|
||||||
|
|
||||||
|
ShaderEditor *ShaderEditorPlugin::get_shader_editor(const Ref<Shader> &p_for_shader) {
|
||||||
|
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
|
||||||
|
if (edited_shaders[i].shader == p_for_shader) {
|
||||||
|
return edited_shaders[i].shader_editor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderEditorPlugin::save_external_data() {
|
void ShaderEditorPlugin::save_external_data() {
|
||||||
shader_editor->save_external_data();
|
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
|
||||||
|
if (edited_shaders[i].shader_editor) {
|
||||||
|
edited_shaders[i].shader_editor->save_external_data();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderEditorPlugin::apply_changes() {
|
void ShaderEditorPlugin::apply_changes() {
|
||||||
shader_editor->apply_shaders();
|
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
|
||||||
|
if (edited_shaders[i].shader_editor) {
|
||||||
|
edited_shaders[i].shader_editor->apply_shaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderEditorPlugin::_shader_selected(int p_index) {
|
||||||
|
shader_tabs->set_current_tab(p_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderEditorPlugin::_close_shader(int p_index) {
|
||||||
|
int index = shader_tabs->get_current_tab();
|
||||||
|
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
|
||||||
|
Control *c = shader_tabs->get_tab_control(index);
|
||||||
|
memdelete(c);
|
||||||
|
edited_shaders.remove_at(index);
|
||||||
|
_update_shader_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderEditorPlugin::_resource_saved(Object *obj) {
|
||||||
|
// May have been renamed on save.
|
||||||
|
for (uint32_t i = 0; i < edited_shaders.size(); i++) {
|
||||||
|
if (edited_shaders[i].shader.ptr() == obj) {
|
||||||
|
_update_shader_list();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderEditorPlugin::_menu_item_pressed(int p_index) {
|
||||||
|
switch (p_index) {
|
||||||
|
case FILE_NEW: {
|
||||||
|
String base_path = FileSystemDock::get_singleton()->get_current_path();
|
||||||
|
shader_create_dialog->config(base_path.plus_file("new_shader"), false, false, 0);
|
||||||
|
shader_create_dialog->popup_centered();
|
||||||
|
} break;
|
||||||
|
case FILE_OPEN: {
|
||||||
|
InspectorDock::get_singleton()->open_resource("Shader");
|
||||||
|
} break;
|
||||||
|
case FILE_SAVE: {
|
||||||
|
int index = shader_tabs->get_current_tab();
|
||||||
|
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
|
||||||
|
EditorNode::get_singleton()->save_resource(edited_shaders[index].shader);
|
||||||
|
} break;
|
||||||
|
case FILE_SAVE_AS: {
|
||||||
|
int index = shader_tabs->get_current_tab();
|
||||||
|
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
|
||||||
|
String path = edited_shaders[index].shader->get_path();
|
||||||
|
if (!path.is_resource_file()) {
|
||||||
|
path = "";
|
||||||
|
}
|
||||||
|
EditorNode::get_singleton()->save_resource_as(edited_shaders[index].shader, path);
|
||||||
|
} break;
|
||||||
|
case FILE_INSPECT: {
|
||||||
|
int index = shader_tabs->get_current_tab();
|
||||||
|
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
|
||||||
|
EditorNode::get_singleton()->push_item(edited_shaders[index].shader.ptr());
|
||||||
|
} break;
|
||||||
|
case FILE_CLOSE: {
|
||||||
|
_close_shader(shader_tabs->get_current_tab());
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderEditorPlugin::_shader_created(Ref<Shader> p_shader) {
|
||||||
|
EditorNode::get_singleton()->push_item(p_shader.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderEditorPlugin::ShaderEditorPlugin() {
|
ShaderEditorPlugin::ShaderEditorPlugin() {
|
||||||
shader_editor = memnew(ShaderEditor);
|
main_split = memnew(HSplitContainer);
|
||||||
|
|
||||||
shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
|
VBoxContainer *vb = memnew(VBoxContainer);
|
||||||
button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader"), shader_editor);
|
|
||||||
button->hide();
|
|
||||||
|
|
||||||
_2d = false;
|
HBoxContainer *file_hb = memnew(HBoxContainer);
|
||||||
|
vb->add_child(file_hb);
|
||||||
|
file_menu = memnew(MenuButton);
|
||||||
|
file_menu->set_text(TTR("File"));
|
||||||
|
file_menu->get_popup()->add_item(TTR("New Shader"), FILE_NEW);
|
||||||
|
file_menu->get_popup()->add_separator();
|
||||||
|
file_menu->get_popup()->add_item(TTR("Load Shader"), FILE_OPEN);
|
||||||
|
file_menu->get_popup()->add_item(TTR("Save Shader"), FILE_SAVE);
|
||||||
|
file_menu->get_popup()->add_item(TTR("Save Shader As"), FILE_SAVE_AS);
|
||||||
|
file_menu->get_popup()->add_separator();
|
||||||
|
file_menu->get_popup()->add_item(TTR("Open Shader in Inspector"), FILE_INSPECT);
|
||||||
|
file_menu->get_popup()->add_separator();
|
||||||
|
file_menu->get_popup()->add_item(TTR("Close Shader"), FILE_CLOSE);
|
||||||
|
file_menu->get_popup()->connect("id_pressed", callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed));
|
||||||
|
file_hb->add_child(file_menu);
|
||||||
|
|
||||||
|
for (int i = 1; i < FILE_MAX; i++) {
|
||||||
|
file_menu->get_popup()->set_item_disabled(file_menu->get_popup()->get_item_index(i), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_list = memnew(ItemList);
|
||||||
|
shader_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
vb->add_child(shader_list);
|
||||||
|
shader_list->connect("item_selected", callable_mp(this, &ShaderEditorPlugin::_shader_selected));
|
||||||
|
|
||||||
|
main_split->add_child(vb);
|
||||||
|
vb->set_custom_minimum_size(Size2(200, 300) * EDSCALE);
|
||||||
|
|
||||||
|
shader_tabs = memnew(TabContainer);
|
||||||
|
shader_tabs->set_tabs_visible(false);
|
||||||
|
shader_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
main_split->add_child(shader_tabs);
|
||||||
|
Ref<StyleBoxEmpty> empty;
|
||||||
|
empty.instantiate();
|
||||||
|
shader_tabs->add_theme_style_override("panel", empty);
|
||||||
|
|
||||||
|
button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Shader Editor"), main_split);
|
||||||
|
|
||||||
|
// Defer connect because Editor class is not in the binding system yet.
|
||||||
|
EditorNode::get_singleton()->call_deferred("connect", "resource_saved", callable_mp(this, &ShaderEditorPlugin::_resource_saved), varray(), CONNECT_DEFERRED);
|
||||||
|
|
||||||
|
shader_create_dialog = memnew(ShaderCreateDialog);
|
||||||
|
vb->add_child(shader_create_dialog);
|
||||||
|
shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderEditorPlugin::~ShaderEditorPlugin() {
|
ShaderEditorPlugin::~ShaderEditorPlugin() {
|
||||||
|
|
|
@ -42,6 +42,11 @@
|
||||||
#include "scene/resources/shader.h"
|
#include "scene/resources/shader.h"
|
||||||
#include "servers/rendering/shader_warnings.h"
|
#include "servers/rendering/shader_warnings.h"
|
||||||
|
|
||||||
|
class ItemList;
|
||||||
|
class VisualShaderEditor;
|
||||||
|
class HSplitContainer;
|
||||||
|
class ShaderCreateDialog;
|
||||||
|
|
||||||
class ShaderTextEditor : public CodeTextEditor {
|
class ShaderTextEditor : public CodeTextEditor {
|
||||||
GDCLASS(ShaderTextEditor, CodeTextEditor);
|
GDCLASS(ShaderTextEditor, CodeTextEditor);
|
||||||
|
|
||||||
|
@ -160,9 +165,40 @@ public:
|
||||||
class ShaderEditorPlugin : public EditorPlugin {
|
class ShaderEditorPlugin : public EditorPlugin {
|
||||||
GDCLASS(ShaderEditorPlugin, EditorPlugin);
|
GDCLASS(ShaderEditorPlugin, EditorPlugin);
|
||||||
|
|
||||||
bool _2d;
|
struct EditedShader {
|
||||||
ShaderEditor *shader_editor = nullptr;
|
Ref<Shader> shader;
|
||||||
|
ShaderEditor *shader_editor = nullptr;
|
||||||
|
VisualShaderEditor *visual_shader_editor = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalVector<EditedShader> edited_shaders;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FILE_NEW,
|
||||||
|
FILE_OPEN,
|
||||||
|
FILE_SAVE,
|
||||||
|
FILE_SAVE_AS,
|
||||||
|
FILE_INSPECT,
|
||||||
|
FILE_CLOSE,
|
||||||
|
FILE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
HSplitContainer *main_split = nullptr;
|
||||||
|
ItemList *shader_list = nullptr;
|
||||||
|
TabContainer *shader_tabs = nullptr;
|
||||||
|
|
||||||
Button *button = nullptr;
|
Button *button = nullptr;
|
||||||
|
MenuButton *file_menu = nullptr;
|
||||||
|
|
||||||
|
ShaderCreateDialog *shader_create_dialog = nullptr;
|
||||||
|
|
||||||
|
void _update_shader_list();
|
||||||
|
void _shader_selected(int p_index);
|
||||||
|
void _menu_item_pressed(int p_index);
|
||||||
|
void _resource_saved(Object *obj);
|
||||||
|
void _close_shader(int p_index);
|
||||||
|
|
||||||
|
void _shader_created(Ref<Shader> p_shader);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual String get_name() const override { return "Shader"; }
|
virtual String get_name() const override { return "Shader"; }
|
||||||
|
@ -172,7 +208,7 @@ public:
|
||||||
virtual void make_visible(bool p_visible) override;
|
virtual void make_visible(bool p_visible) override;
|
||||||
virtual void selected_notify() override;
|
virtual void selected_notify() override;
|
||||||
|
|
||||||
ShaderEditor *get_shader_editor() const { return shader_editor; }
|
ShaderEditor *get_shader_editor(const Ref<Shader> &p_for_shader);
|
||||||
|
|
||||||
virtual void save_external_data() override;
|
virtual void save_external_data() override;
|
||||||
virtual void apply_changes() override;
|
virtual void apply_changes() override;
|
||||||
|
|
|
@ -5645,48 +5645,6 @@ VisualShaderEditor::VisualShaderEditor() {
|
||||||
property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited));
|
property_editor->connect("variant_changed", callable_mp(this, &VisualShaderEditor::_port_edited));
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////
|
|
||||||
|
|
||||||
void VisualShaderEditorPlugin::edit(Object *p_object) {
|
|
||||||
visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VisualShaderEditorPlugin::handles(Object *p_object) const {
|
|
||||||
return p_object->is_class("VisualShader");
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisualShaderEditorPlugin::make_visible(bool p_visible) {
|
|
||||||
if (p_visible) {
|
|
||||||
//editor->hide_animation_player_editors();
|
|
||||||
//editor->animation_panel_make_visible(true);
|
|
||||||
button->show();
|
|
||||||
EditorNode::get_singleton()->make_bottom_panel_item_visible(visual_shader_editor);
|
|
||||||
visual_shader_editor->update_nodes();
|
|
||||||
visual_shader_editor->set_process_input(true);
|
|
||||||
//visual_shader_editor->set_process(true);
|
|
||||||
} else {
|
|
||||||
if (visual_shader_editor->is_visible_in_tree()) {
|
|
||||||
EditorNode::get_singleton()->hide_bottom_panel();
|
|
||||||
}
|
|
||||||
button->hide();
|
|
||||||
visual_shader_editor->set_process_input(false);
|
|
||||||
//visual_shader_editor->set_process(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualShaderEditorPlugin::VisualShaderEditorPlugin() {
|
|
||||||
visual_shader_editor = memnew(VisualShaderEditor);
|
|
||||||
visual_shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
|
|
||||||
|
|
||||||
button = EditorNode::get_singleton()->add_bottom_panel_item(TTR("VisualShader"), visual_shader_editor);
|
|
||||||
button->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualShaderEditorPlugin::~VisualShaderEditorPlugin() {
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////
|
|
||||||
|
|
||||||
class VisualShaderNodePluginInputEditor : public OptionButton {
|
class VisualShaderNodePluginInputEditor : public OptionButton {
|
||||||
GDCLASS(VisualShaderNodePluginInputEditor, OptionButton);
|
GDCLASS(VisualShaderNodePluginInputEditor, OptionButton);
|
||||||
|
|
||||||
|
|
|
@ -493,23 +493,6 @@ public:
|
||||||
VisualShaderEditor();
|
VisualShaderEditor();
|
||||||
};
|
};
|
||||||
|
|
||||||
class VisualShaderEditorPlugin : public EditorPlugin {
|
|
||||||
GDCLASS(VisualShaderEditorPlugin, EditorPlugin);
|
|
||||||
|
|
||||||
VisualShaderEditor *visual_shader_editor = nullptr;
|
|
||||||
Button *button = nullptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual String get_name() const override { return "VisualShader"; }
|
|
||||||
bool has_main_screen() const override { return false; }
|
|
||||||
virtual void edit(Object *p_object) override;
|
|
||||||
virtual bool handles(Object *p_object) const override;
|
|
||||||
virtual void make_visible(bool p_visible) override;
|
|
||||||
|
|
||||||
VisualShaderEditorPlugin();
|
|
||||||
~VisualShaderEditorPlugin();
|
|
||||||
};
|
|
||||||
|
|
||||||
class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {
|
class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {
|
||||||
GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin);
|
GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue