Эх сурвалжийг харах

[godot] Custom materials on the skeleton level.

badlogic 3 жил өмнө
parent
commit
3785147ba3

+ 21 - 0
spine-godot/example/examples/09-custom-material/custom-material.tscn

@@ -0,0 +1,21 @@
+[gd_scene load_steps=4 format=2]
+
+[ext_resource path="res://assets/spineboy/spinebody-data-res.tres" type="SpineSkeletonDataResource" id=1]
+
+[sub_resource type="Shader" id=1]
+code = "shader_type canvas_item;
+
+void fragment() {
+  COLOR = vec4(0.4, 0.6, 0.9, 1.0);
+}"
+
+[sub_resource type="ShaderMaterial" id=2]
+shader = SubResource( 1 )
+
+[node name="Node2D" type="Node2D"]
+
+[node name="SpineSprite" type="SpineSprite" parent="."]
+position = Vector2( 471, 482 )
+scale = Vector2( 0.546374, 0.546373 )
+skeleton_data_res = ExtResource( 1 )
+normal_material = SubResource( 2 )

+ 57 - 3
spine-godot/spine_godot/SpineSprite.cpp

@@ -50,6 +50,15 @@ void SpineSprite::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_update_mode", "v"), &SpineSprite::set_update_mode);
 	ClassDB::bind_method(D_METHOD("get_update_mode"), &SpineSprite::get_update_mode);
 
+	ClassDB::bind_method(D_METHOD("set_normal_material", "material"), &SpineSprite::set_normal_material);
+	ClassDB::bind_method(D_METHOD("get_normal_material"), &SpineSprite::get_normal_material);
+	ClassDB::bind_method(D_METHOD("set_additive_material", "material"), &SpineSprite::set_additive_material);
+	ClassDB::bind_method(D_METHOD("get_additive_material"), &SpineSprite::get_additive_material);
+	ClassDB::bind_method(D_METHOD("set_multiply_material", "material"), &SpineSprite::set_multiply_material);
+	ClassDB::bind_method(D_METHOD("get_multiply_material"), &SpineSprite::get_multiply_material);
+	ClassDB::bind_method(D_METHOD("set_screen_material", "material"), &SpineSprite::set_screen_material);
+	ClassDB::bind_method(D_METHOD("get_screen_material"), &SpineSprite::get_screen_material);
+
 	ClassDB::bind_method(D_METHOD("update_skeleton", "delta"), &SpineSprite::update_skeleton);
 	ClassDB::bind_method(D_METHOD("new_skin", "name"), &SpineSprite::new_skin);
 
@@ -67,6 +76,11 @@ void SpineSprite::_bind_methods() {
 
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton_data_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineSkeletonDataResource"), "set_skeleton_data_res", "get_skeleton_data_res");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Process,Physics,Manual"), "set_update_mode", "get_update_mode");
+	ADD_GROUP("Materials", "");
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_normal_material", "get_normal_material");
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "additive_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_additive_material", "get_additive_material");
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multiply_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_multiply_material", "get_multiply_material");
+	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "screen_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_screen_material", "get_screen_material");
 
 	BIND_ENUM_CONSTANT(UpdateMode::UpdateMode_Process)
 	BIND_ENUM_CONSTANT(UpdateMode::UpdateMode_Physics)
@@ -91,7 +105,7 @@ SpineSprite::SpineSprite() : update_mode(UpdateMode_Process), skeleton_clipper(n
 		default_materials[spine::BlendMode_Multiply] = material_multiply;
 
 		Ref<CanvasItemMaterial> material_screen(memnew(CanvasItemMaterial));
-		material_screen->set_blend_mode(CanvasItemMaterial::BLEND_MODE_MIX);
+		material_screen->set_blend_mode(CanvasItemMaterial::BLEND_MODE_SUB);
 		default_materials[spine::BlendMode_Screen] = material_screen;
 	}
 	sprite_count++;
@@ -446,9 +460,17 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton) {
 		}
 		skeleton_clipper->clipEnd(*slot);
 
-		if (mesh_ins->get_material()->is_class("CanvasItemMaterial")) {
-			mesh_ins->set_material(default_materials[slot->getData().getBlendMode()]);
+		spine::BlendMode blend_mode = slot->getData().getBlendMode();
+		Ref<Material> custom_material;
+		switch (blend_mode) {
+		case spine::BlendMode_Normal: custom_material = normal_material; break;
+		case spine::BlendMode_Additive: custom_material = additive_material; break;
+		case spine::BlendMode_Multiply: custom_material = multiply_material; break;
+		case spine::BlendMode_Screen: custom_material = screen_material; break;
+		default: ;
 		}
+		if (custom_material.is_valid()) mesh_ins->set_material(custom_material);
+		else mesh_ins->set_material(default_materials[slot->getData().getBlendMode()]);
 	}
 	skeleton_clipper->clipEnd();
 }
@@ -518,6 +540,38 @@ Ref<SpineSkin> SpineSprite::new_skin(const String& name) {
 	return skin;
 }
 
+Ref<Material> SpineSprite::get_normal_material() {
+	return normal_material;
+}
+
+void SpineSprite::set_normal_material(Ref<Material> material) {
+	normal_material = material;
+}
+
+Ref<Material> SpineSprite::get_additive_material() {
+	return additive_material;
+}
+
+void SpineSprite::set_additive_material(Ref<Material> material) {
+	additive_material = material;
+}
+
+Ref<Material> SpineSprite::get_multiply_material() {
+	return multiply_material;
+}
+
+void SpineSprite::set_multiply_material(Ref<Material> material) {
+	multiply_material = material;
+}
+
+Ref<Material> SpineSprite::get_screen_material() {
+	return screen_material;
+}
+
+void SpineSprite::set_screen_material(Ref<Material> material) {
+	screen_material = material;
+}
+
 #ifdef TOOLS_ENABLED
 Rect2 SpineSprite::_edit_get_rect() const {
 	if (skeleton_data_res.is_valid() && skeleton_data_res->is_skeleton_data_loaded()) {

+ 20 - 0
spine-godot/spine_godot/SpineSprite.h

@@ -58,6 +58,10 @@ protected:
 	Vector<MeshInstance2D *> mesh_instances;
 	spine::SkeletonClipping *skeleton_clipper;
 	static Ref<CanvasItemMaterial> default_materials[4];
+	Ref<Material> normal_material;
+	Ref<Material> additive_material;
+	Ref<Material> multiply_material;
+	Ref<Material> screen_material;
 	
 	static void _bind_methods();
 	void _notification(int what);
@@ -95,6 +99,22 @@ public:
 
 	Ref<SpineSkin> new_skin(const String &name);
 
+	Ref<Material> get_normal_material();
+
+	void set_normal_material(Ref<Material> material);
+
+	Ref<Material> get_additive_material();
+
+	void set_additive_material(Ref<Material> material);
+
+	Ref<Material> get_multiply_material();
+
+	void set_multiply_material(Ref<Material> material);
+
+	Ref<Material> get_screen_material();
+
+	void set_screen_material(Ref<Material> material);
+
 #ifdef TOOLS_ENABLED
 	virtual Rect2 _edit_get_rect() const;
 	virtual bool _edit_use_rect() const;