diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 107ae51d..6715c073 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -36,3 +36,4 @@ add_e2d_sample(02) add_e2d_sample(03) add_e2d_sample(04) add_e2d_sample(05) +add_e2d_sample(07) diff --git a/samples/bin/library/raptor/export/raptor-pro.json b/samples/bin/library/raptor/export/raptor-pro.json new file mode 100644 index 00000000..47afbe58 --- /dev/null +++ b/samples/bin/library/raptor/export/raptor-pro.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c8d0e5057c92306900f39879e51642500b841825cedb47833bbfa129978b5757 +size 172896 diff --git a/samples/bin/library/raptor/export/raptor-pro.skel b/samples/bin/library/raptor/export/raptor-pro.skel new file mode 100644 index 00000000..235f7aa0 --- /dev/null +++ b/samples/bin/library/raptor/export/raptor-pro.skel @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83c00999f00c4ac395ba063291d02131fb2a8869cb6d8f4fd20bc15131d52d54 +size 63077 diff --git a/samples/bin/library/raptor/export/raptor.atlas b/samples/bin/library/raptor/export/raptor.atlas new file mode 100644 index 00000000..09e4ce87 --- /dev/null +++ b/samples/bin/library/raptor/export/raptor.atlas @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19b38bacd3e0cb4b41df20d88d2097e9886745b535bf821004736f7ae7582736 +size 4224 diff --git a/samples/bin/library/raptor/export/raptor.png b/samples/bin/library/raptor/export/raptor.png new file mode 100644 index 00000000..6e6a20d2 --- /dev/null +++ b/samples/bin/library/raptor/export/raptor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:879d84230024a1529ea994e7cd6416c5883f4b74b0d268b5e2dea1cbe2d00777 +size 480392 diff --git a/samples/bin/library/spine_material.json b/samples/bin/library/spine_material.json new file mode 100644 index 00000000..ecaf4333 --- /dev/null +++ b/samples/bin/library/spine_material.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b20bd767ea8ad744e3af8c4bd353f010e9f4d65f17c34b70a974baf117ff7ecb +size 349 diff --git a/samples/bin/library/spine_raptor.json b/samples/bin/library/spine_raptor.json new file mode 100644 index 00000000..fcd252a0 --- /dev/null +++ b/samples/bin/library/spine_raptor.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b2d2131b3fe0d761de597e316a9001f3fefc7c03c503ec9b2bac538543893e1 +size 131 diff --git a/samples/bin/library/spine_shader.frag b/samples/bin/library/spine_shader.frag new file mode 100644 index 00000000..e0fff40b --- /dev/null +++ b/samples/bin/library/spine_shader.frag @@ -0,0 +1,11 @@ +#version 120 + +uniform sampler2D u_texture; + +varying vec4 v_tint; +varying vec2 v_st; + +void main() { + vec2 st = vec2(v_st.s, v_st.t); + gl_FragColor = texture2D(u_texture, st) * v_tint; +} diff --git a/samples/bin/library/spine_shader.json b/samples/bin/library/spine_shader.json new file mode 100644 index 00000000..b13c1dcf --- /dev/null +++ b/samples/bin/library/spine_shader.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa42a9a09042744abe4f9ef1d50b190baef49e43ccd979ac99e491743d17dfec +size 81 diff --git a/samples/bin/library/spine_shader.vert b/samples/bin/library/spine_shader.vert new file mode 100644 index 00000000..edfe96a4 --- /dev/null +++ b/samples/bin/library/spine_shader.vert @@ -0,0 +1,16 @@ +#version 120 + +uniform mat4 u_matrix_mvp; + +attribute vec3 a_vertex; +attribute vec4 a_tint; +attribute vec2 a_st; + +varying vec4 v_tint; +varying vec2 v_st; + +void main() { + v_st = a_st; + v_tint = a_tint; + gl_Position = vec4(a_vertex, 1.0) * u_matrix_mvp; +} diff --git a/samples/sources/sample_07/sample_07.cpp b/samples/sources/sample_07/sample_07.cpp new file mode 100644 index 00000000..b0a750e3 --- /dev/null +++ b/samples/sources/sample_07/sample_07.cpp @@ -0,0 +1,113 @@ +/******************************************************************************* + * This file is part of the "Enduro2D" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "../common.hpp" +using namespace e2d; + +namespace +{ + class game_system final : public ecs::system { + public: + void process(ecs::registry& owner) override { + E2D_UNUSED(owner); + const keyboard& k = the().keyboard(); + + if ( k.is_key_just_released(keyboard_key::f12) ) { + the().toggle_visible(!the().visible()); + } + + if ( k.is_key_just_released(keyboard_key::escape) ) { + the().set_should_close(true); + } + + if ( k.is_key_pressed(keyboard_key::lsuper) && k.is_key_just_released(keyboard_key::enter) ) { + the().toggle_fullscreen(!the().fullscreen()); + } + } + }; + + class camera_system final : public ecs::system { + public: + void process(ecs::registry& owner) override { + owner.for_joined_components( + [](const ecs::const_entity&, camera& cam){ + if ( !cam.target() ) { + cam.viewport( + the().real_size()); + cam.projection(math::make_orthogonal_lh_matrix4( + the().real_size().cast_to(), 0.f, 1000.f)); + } + }); + } + }; + + class game final : public starter::application { + public: + bool initialize() final { + return create_scene() + && create_camera() + && create_systems(); + } + private: + bool create_scene() { + auto spine_res = the().load_asset("spine_raptor.json"); + auto spine_mat = the().load_asset("spine_material.json"); + + if ( !spine_res || !spine_mat ) { + return false; + } + + auto scene_i = the().instantiate(); + + scene_i->entity_filler() + .component() + .component(node::create(scene_i)); + + node_iptr scene_r = scene_i->get_component().get().node(); + + auto spine_i = the().instantiate(); + spine_i->entity_filler() + .component(node::create(spine_i, scene_r)) + .component(renderer() + .materials({spine_mat})) + .component(spine_renderer(spine_res)) + .component(spine_player(spine_res) + .set_animation(0, "walk", true) + .add_animation(1, "gun-grab", false, secf(2.0f))); + + node_iptr spine_n = spine_i->get_component().get().node(); + spine_n->scale(v3f(0.25f)); + spine_n->translation(v3f{-40.f, -100.f, 0.0f}); + return true; + } + + bool create_camera() { + auto camera_i = the().instantiate(); + camera_i->entity_filler() + .component(camera() + .background({1.f, 0.4f, 0.f, 1.f})) + .component(node::create(camera_i)); + return true; + } + + bool create_systems() { + ecs::registry_filler(the().registry()) + .system(world::priority_update) + .system(world::priority_pre_render); + return true; + } + }; +} + +int e2d_main(int argc, char *argv[]) { + const auto starter_params = starter::parameters( + engine::parameters("sample_07", "enduro2d") + .timer_params(engine::timer_parameters() + .maximal_framerate(100))); + modules::initialize(argc, argv, starter_params).start(); + modules::shutdown(); + return 0; +} diff --git a/sources/enduro2d/high/assets/spine_model_asset.cpp b/sources/enduro2d/high/assets/spine_model_asset.cpp index 473ab5d3..9d141386 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" : { "skeleton" : { "$ref" : "#/common_definitions/address" }, + "scale" : { "type" : "number" }, "atlas" : { "$ref" : "#/common_definitions/address" }, "premultiplied_alpha" : { "type" : "boolean" }, "mix_animations" : { @@ -127,15 +128,22 @@ namespace nullptr), spAtlas_dispose); + float skeleton_scale = 1.0f; + if ( root.HasMember("scale") ) { + if ( !json_utils::try_parse_value(root["scale"], skeleton_scale) ) { + the().error("SPINE: Incorrect formating of 'scale' property"); + } + } + + skeleton_json_ptr skeleton_json(spSkeletonJson_create(atlas.get()), spSkeletonJson_dispose); + skeleton_json->scale = skeleton_scale; + E2D_ASSERT(root.HasMember("skeleton") && root["skeleton"].IsString()); binary_asset::load_result skeleton_data = library.load_asset( path::combine(parent_address, root["skeleton"].GetString())); - skeleton_json_ptr json( - spSkeletonJson_create(atlas.get()), - spSkeletonJson_dispose); spine_model::skeleton_data_ptr skeleton( spSkeletonJson_readSkeletonData( - json.get(), + skeleton_json.get(), reinterpret_cast(skeleton_data->content().data())), spSkeletonData_dispose); 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 37bf923d..2c8459eb 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 @@ -26,6 +26,7 @@ namespace const str_hash matrix_v_property_hash = "u_matrix_v"; const str_hash matrix_p_property_hash = "u_matrix_p"; const str_hash matrix_vp_property_hash = "u_matrix_vp"; + const str_hash matrix_mvp_property_hash = "u_matrix_mvp"; const str_hash game_time_property_hash = "u_game_time"; const str_hash sprite_texture_sampler_hash = "u_texture"; } @@ -52,15 +53,15 @@ namespace e2d::render_system_impl : m4f::identity(); const std::pair cam_w_inv = math::inversed(cam_w); - const m4f& m_v = cam_w_inv.second + view_mat_ = cam_w_inv.second ? cam_w_inv.first : m4f::identity(); - const m4f& m_p = cam.projection(); + proj_mat_ = cam.projection(); batcher_.flush() - .property(matrix_v_property_hash, m_v) - .property(matrix_p_property_hash, m_p) - .property(matrix_vp_property_hash, m_v * m_p) + .property(matrix_v_property_hash, view_mat_) + .property(matrix_p_property_hash, proj_mat_) + .property(matrix_vp_property_hash, view_mat_ * proj_mat_) .property(game_time_property_hash, engine.time()); render.execute(render::command_block<3>() @@ -249,6 +250,7 @@ namespace e2d::render_system_impl spSkeletonClipping* clipper = spine_r.clipper().operator->(); spVertexEffect* effect = spine_r.effect().operator->(); const material_asset::ptr& mat_a = node_r.materials().front(); + const m4f& mvp = node->world_matrix() * view_mat_ * proj_mat_; float dt = 0.01f; if ( !skeleton || !clipper || !mat_a ) { @@ -271,6 +273,7 @@ namespace e2d::render_system_impl if ( effect ) { effect->begin(effect, skeleton); } + for ( int i = 0; i < skeleton->slotsCount; ++i ) { spSlot* slot = skeleton->drawOrder[i]; @@ -381,6 +384,7 @@ namespace e2d::render_system_impl .texture(texture) .min_filter(render::sampler_min_filter::linear) .mag_filter(render::sampler_mag_filter::linear)) + .property(matrix_mvp_property_hash, mvp) .merge(node_r.properties()); batcher_.batch( diff --git a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp index 05c82cff..6f584a4b 100644 --- a/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp +++ b/sources/enduro2d/high/systems/render_system_impl/render_system_drawer.hpp @@ -65,6 +65,8 @@ namespace e2d::render_system_impl batcher_type& batcher_; std::vector& spine_vertices_; render::property_block property_cache_; + m4f view_mat_; + m4f proj_mat_; }; public: drawer(engine& e, debug& d, render& r);