From c2240a2a714526e226ead5a20e3a070bb3eaaef6 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 26 Dec 2017 13:52:09 -0300 Subject: [PATCH] A promise is a promise, so added ability to load and save shaders as text files, closes #14431 --- scene/register_scene_types.cpp | 16 +++++++ scene/resources/shader.cpp | 77 ++++++++++++++++++++++++++++++++++ scene/resources/shader.h | 17 +++++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 39e66987255..0c8837ee1ae 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -200,6 +200,9 @@ static ResourceFormatLoaderDynamicFont *resource_loader_dynamic_font = NULL; static ResourceFormatLoaderStreamTexture *resource_loader_stream_texture = NULL; +static ResourceFormatSaverShader *resource_saver_shader = NULL; +static ResourceFormatLoaderShader *resource_loader_shader = NULL; + void register_scene_types() { SceneStringNames::create(); @@ -607,6 +610,12 @@ void register_scene_types() { resource_loader_text = memnew(ResourceFormatLoaderText); ResourceLoader::add_resource_format_loader(resource_loader_text, true); + resource_saver_shader = memnew(ResourceFormatSaverShader); + ResourceSaver::add_resource_format_saver(resource_saver_shader, true); + + resource_loader_shader = memnew(ResourceFormatLoaderShader); + ResourceLoader::add_resource_format_loader(resource_loader_shader, true); + for (int i = 0; i < 20; i++) { GLOBAL_DEF("layer_names/2d_render/layer_" + itos(i + 1), ""); GLOBAL_DEF("layer_names/2d_physics/layer_" + itos(i + 1), ""); @@ -632,6 +641,13 @@ void unregister_scene_types() { memdelete(resource_loader_text); } + if (resource_saver_shader) { + memdelete(resource_saver_shader); + } + if (resource_loader_shader) { + memdelete(resource_loader_shader); + } + SpatialMaterial::finish_shaders(); ParticlesMaterial::finish_shaders(); CanvasItemMaterial::finish_shaders(); diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 66df7dfda88..207c50f6738 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -151,3 +151,80 @@ Shader::~Shader() { VisualServer::get_singleton()->free(shader); } +//////////// + +RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error) { + + if (r_error) + *r_error = ERR_FILE_CANT_OPEN; + + Ref shader; + shader.instance(); + + Vector buffer = FileAccess::get_file_as_array(p_path); + + String str; + str.parse_utf8((const char *)buffer.ptr(), buffer.size()); + + shader->set_code(str); + + if (r_error) + *r_error = OK; + + return shader; +} + +void ResourceFormatLoaderShader::get_recognized_extensions(List *p_extensions) const { + + p_extensions->push_back("shader"); +} + +bool ResourceFormatLoaderShader::handles_type(const String &p_type) const { + + return (p_type == "Shader"); +} + +String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const { + + String el = p_path.get_extension().to_lower(); + if (el == "shader") + return "Shader"; + return ""; +} + +Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { + + Ref shader = p_resource; + ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER); + + String source = shader->get_code(); + + Error err; + FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err); + + if (err) { + + ERR_FAIL_COND_V(err, err); + } + + file->store_string(source); + if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) { + memdelete(file); + return ERR_CANT_CREATE; + } + file->close(); + memdelete(file); + + return OK; +} + +void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List *p_extensions) const { + + if (Object::cast_to(*p_resource)) { + p_extensions->push_back("shader"); + } +} +bool ResourceFormatSaverShader::recognize(const RES &p_resource) const { + + return Object::cast_to(*p_resource) != NULL; +} diff --git a/scene/resources/shader.h b/scene/resources/shader.h index 5cc70629c7e..78d73a33e26 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -31,6 +31,7 @@ #define SHADER_H #include "io/resource_loader.h" +#include "io/resource_saver.h" #include "resource.h" #include "scene/resources/texture.h" @@ -38,7 +39,6 @@ class Shader : public Resource { GDCLASS(Shader, Resource); OBJ_SAVE_TYPE(Shader); - RES_BASE_EXTENSION("shd"); public: enum Mode { @@ -95,4 +95,19 @@ public: VARIANT_ENUM_CAST(Shader::Mode); +class ResourceFormatLoaderShader : public ResourceFormatLoader { +public: + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual void get_recognized_extensions(List *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; +}; + +class ResourceFormatSaverShader : public ResourceFormatSaver { +public: + virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0); + virtual void get_recognized_extensions(const RES &p_resource, List *p_extensions) const; + virtual bool recognize(const RES &p_resource) const; +}; + #endif // SHADER_H