diff --git a/spine-godot/example/examples/09-custom-material/custom-material.tscn b/spine-godot/example/examples/09-custom-material/custom-material.tscn new file mode 100644 index 000000000..17f6d21c0 --- /dev/null +++ b/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 ) diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index 2de327ff1..5abeb54ef 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/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 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 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 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 SpineSprite::new_skin(const String& name) { return skin; } +Ref SpineSprite::get_normal_material() { + return normal_material; +} + +void SpineSprite::set_normal_material(Ref material) { + normal_material = material; +} + +Ref SpineSprite::get_additive_material() { + return additive_material; +} + +void SpineSprite::set_additive_material(Ref material) { + additive_material = material; +} + +Ref SpineSprite::get_multiply_material() { + return multiply_material; +} + +void SpineSprite::set_multiply_material(Ref material) { + multiply_material = material; +} + +Ref SpineSprite::get_screen_material() { + return screen_material; +} + +void SpineSprite::set_screen_material(Ref 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()) { diff --git a/spine-godot/spine_godot/SpineSprite.h b/spine-godot/spine_godot/SpineSprite.h index 77c5e3a97..b842de3a5 100644 --- a/spine-godot/spine_godot/SpineSprite.h +++ b/spine-godot/spine_godot/SpineSprite.h @@ -58,6 +58,10 @@ protected: Vector mesh_instances; spine::SkeletonClipping *skeleton_clipper; static Ref default_materials[4]; + Ref normal_material; + Ref additive_material; + Ref multiply_material; + Ref screen_material; static void _bind_methods(); void _notification(int what); @@ -95,6 +99,22 @@ public: Ref new_skin(const String &name); + Ref get_normal_material(); + + void set_normal_material(Ref material); + + Ref get_additive_material(); + + void set_additive_material(Ref material); + + Ref get_multiply_material(); + + void set_multiply_material(Ref material); + + Ref get_screen_material(); + + void set_screen_material(Ref material); + #ifdef TOOLS_ENABLED virtual Rect2 _edit_get_rect() const; virtual bool _edit_use_rect() const;