From c355291adee7fde74b83e196e0db66ebb367cc32 Mon Sep 17 00:00:00 2001 From: "andrey.zhirnov" Date: Tue, 27 Aug 2019 14:10:18 +0300 Subject: [PATCH] added ability to use atlas with premultiplied alpha --- headers/enduro2d/high/spine_model.hpp | 4 +++- samples/bin/library/spine_coin.json | 1 + samples/sources/sample_07/sample_07.cpp | 2 -- sources/enduro2d/high/assets/spine_model_asset.cpp | 13 +++++++++++-- sources/enduro2d/high/spine_model.cpp | 9 ++++++++- .../render_system_impl/render_system_drawer.cpp | 14 ++++++++++---- sources/enduro2d/high/systems/spine_system.cpp | 1 - 7 files changed, 33 insertions(+), 11 deletions(-) diff --git a/headers/enduro2d/high/spine_model.hpp b/headers/enduro2d/high/spine_model.hpp index 41e28f1b..c482d459 100644 --- a/headers/enduro2d/high/spine_model.hpp +++ b/headers/enduro2d/high/spine_model.hpp @@ -42,7 +42,7 @@ namespace e2d spine_model& assign(spine_model&& other) noexcept; spine_model& assign(const spine_model& other); - spine_model& set_atlas(atlas_ptr atlas); + spine_model& set_atlas(atlas_ptr atlas, bool premultiplied_alpha); spine_model& set_skeleton(skeleton_data_ptr skeleton); spine_model& set_default_mix(secf duration); @@ -54,10 +54,12 @@ namespace e2d const atlas_ptr& atlas() const noexcept; const skeleton_data_ptr& skeleton() const noexcept; const animation_data_ptr& animation() const noexcept; + bool premultiplied_alpha() const noexcept; private: atlas_ptr atlas_; skeleton_data_ptr skeleton_; animation_data_ptr animation_; + bool premultiplied_alpha_ = false; }; void swap(spine_model& l, spine_model& r) noexcept; diff --git a/samples/bin/library/spine_coin.json b/samples/bin/library/spine_coin.json index 7df2f2c7..c6876a53 100644 --- a/samples/bin/library/spine_coin.json +++ b/samples/bin/library/spine_coin.json @@ -1,5 +1,6 @@ { "atlas" : "coin/coin-pma.atlas", + "premultiplied_alpha" : true, "skeleton" : "coin/coin-pro.skel", "skeleton_scale" : 1.0 } diff --git a/samples/sources/sample_07/sample_07.cpp b/samples/sources/sample_07/sample_07.cpp index a31c79d0..4aeb8bc6 100644 --- a/samples/sources/sample_07/sample_07.cpp +++ b/samples/sources/sample_07/sample_07.cpp @@ -107,7 +107,6 @@ namespace .component(node::create(coin_i, scene_r)) .component(renderer() .materials({spine_mat})) - .component(spine_renderer(spine_coin)) .component(spine_player(spine_coin) .set_animation(0, "animation", true)); @@ -120,7 +119,6 @@ namespace .component(node::create(raptor_gobj_, scene_r)) .component(renderer() .materials({spine_mat})) - .component(spine_renderer(spine_raptor)) .component(spine_player(spine_raptor) .set_animation(0, "walk", true)); diff --git a/sources/enduro2d/high/assets/spine_model_asset.cpp b/sources/enduro2d/high/assets/spine_model_asset.cpp index 80b55501..77df24d5 100644 --- a/sources/enduro2d/high/assets/spine_model_asset.cpp +++ b/sources/enduro2d/high/assets/spine_model_asset.cpp @@ -29,6 +29,7 @@ namespace "additionalProperties" : false, "properties" : { "atlas" : { "$ref" : "#/common_definitions/address" }, + "premultiplied_alpha" : { "type" : "boolean" }, "skeleton" : { "$ref" : "#/common_definitions/address" }, "skeleton_scale" : { "type" : "number" }, "default_animation_mix" : { "type" : "number" }, @@ -279,6 +280,13 @@ namespace parse_animation_mix(mixes_json[i])); } } + + bool pma = false; + if ( root.HasMember("premultiplied_alpha") ) { + if ( !json_utils::try_parse_value(root["premultiplied_alpha"], pma) ) { + the().error("SPINE: Incorrect formating of 'premultiplied_alpha' property"); + } + } E2D_ASSERT(root.HasMember("atlas") && root["atlas"].IsString()); const str atlas_address = root["atlas"].GetString(); @@ -308,13 +316,14 @@ namespace }) .then([ default_animation_mix, - animation_mixes = std::move(animation_mixes) + animation_mixes = std::move(animation_mixes), + pma ](const std::tuple< spine_model::atlas_ptr, spine_model::skeleton_data_ptr >& results){ spine_model content; - content.set_atlas(std::get<0>(results)); + content.set_atlas(std::get<0>(results), pma); content.set_skeleton(std::get<1>(results)); content.set_default_mix(default_animation_mix); for ( const animation_mix& mix : animation_mixes ) { diff --git a/sources/enduro2d/high/spine_model.cpp b/sources/enduro2d/high/spine_model.cpp index 08af0451..ae815632 100644 --- a/sources/enduro2d/high/spine_model.cpp +++ b/sources/enduro2d/high/spine_model.cpp @@ -35,6 +35,7 @@ namespace e2d void spine_model::swap(spine_model& other) noexcept { using std::swap; swap(atlas_, other.atlas_); + swap(premultiplied_alpha_, other.premultiplied_alpha_); swap(skeleton_, other.skeleton_); swap(animation_, other.animation_); } @@ -51,6 +52,7 @@ namespace e2d if ( this != &other ) { spine_model m; m.atlas_ = other.atlas_; + m.premultiplied_alpha_ = other.premultiplied_alpha_; m.skeleton_ = other.skeleton_; m.animation_ = other.animation_; swap(m); @@ -58,8 +60,9 @@ namespace e2d return *this; } - spine_model& spine_model::set_atlas(atlas_ptr atlas) { + spine_model& spine_model::set_atlas(atlas_ptr atlas, bool premultiplied_alpha) { atlas_ = std::move(atlas); + premultiplied_alpha_ = premultiplied_alpha; return *this; } @@ -118,6 +121,10 @@ namespace e2d const spine_model::animation_data_ptr& spine_model::animation() const noexcept { return animation_; } + + bool spine_model::premultiplied_alpha() const noexcept { + return premultiplied_alpha_; + } } namespace e2d diff --git a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp index 6cfaf4d7..331b1ee5 100644 --- a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp +++ b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.cpp @@ -268,8 +268,7 @@ namespace e2d::render_system_impl spSkeletonClipping* clipper = spine_r.clipper().operator->(); spVertexEffect* effect = spine_r.effect().operator->(); const material_asset::ptr& src_mat = node_r.materials().front(); - //const bool use_premultiplied_alpha = spine_r.model()->content().premultiplied_alpha(); - const bool use_premultiplied_alpha = false; // TODO: pma is not supported + const bool use_premultiplied_alpha = spine_r.model()->content().premultiplied_alpha(); if ( !skeleton || !clipper || !src_mat ) { return; @@ -351,10 +350,17 @@ namespace e2d::render_system_impl continue; } - const color32 vert_color( + color vert_colorf = color(skeleton->color.r, skeleton->color.g, skeleton->color.b, skeleton->color.a) * color(slot->color.r, slot->color.g, slot->color.b, slot->color.a) * - color(attachment_color->r, attachment_color->g, attachment_color->b, attachment_color->a)); + color(attachment_color->r, attachment_color->g, attachment_color->b, attachment_color->a); + + if ( use_premultiplied_alpha ) { + vert_colorf.r *= vert_colorf.a; + vert_colorf.g *= vert_colorf.a; + vert_colorf.b *= vert_colorf.a; + } + const color32 vert_color(vert_colorf); render::blending_state blend_mode; switch ( slot->data->blendMode ) { diff --git a/sources/enduro2d/high/systems/spine_system.cpp b/sources/enduro2d/high/systems/spine_system.cpp index 91321d24..605695ca 100644 --- a/sources/enduro2d/high/systems/spine_system.cpp +++ b/sources/enduro2d/high/systems/spine_system.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include