瀏覽代碼

A promise is a promise, so added ability to load and save shaders as text files, closes #14431

Juan Linietsky 7 年之前
父節點
當前提交
c2240a2a71
共有 3 個文件被更改,包括 109 次插入1 次删除
  1. 16 0
      scene/register_scene_types.cpp
  2. 77 0
      scene/resources/shader.cpp
  3. 16 1
      scene/resources/shader.h

+ 16 - 0
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();

+ 77 - 0
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;
+	shader.instance();
+
+	Vector<uint8_t> 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<String> *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> 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<String> *p_extensions) const {
+
+	if (Object::cast_to<Shader>(*p_resource)) {
+		p_extensions->push_back("shader");
+	}
+}
+bool ResourceFormatSaverShader::recognize(const RES &p_resource) const {
+
+	return Object::cast_to<Shader>(*p_resource) != NULL;
+}

+ 16 - 1
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<String> *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<String> *p_extensions) const;
+	virtual bool recognize(const RES &p_resource) const;
+};
+
 #endif // SHADER_H