From ed8fc529d0d852de20dfd044240e184dbffc5b75 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 25 Feb 2020 13:14:52 +0700 Subject: [PATCH] render impl for sliced sprites --- samples/bin/library/prefabs/panel_prefab.json | 12 ++ samples/bin/library/scenes/sample_09.json | 81 ++++---- samples/bin/library/sprites/panel.png | 3 + samples/bin/library/sprites/panel_sprite.json | 6 + .../high/components/sprite_renderer.cpp | 9 +- .../render_system_drawer.cpp | 175 ++++++++++++++---- 6 files changed, 210 insertions(+), 76 deletions(-) create mode 100644 samples/bin/library/prefabs/panel_prefab.json create mode 100644 samples/bin/library/sprites/panel.png create mode 100644 samples/bin/library/sprites/panel_sprite.json diff --git a/samples/bin/library/prefabs/panel_prefab.json b/samples/bin/library/prefabs/panel_prefab.json new file mode 100644 index 00000000..6c597f5c --- /dev/null +++ b/samples/bin/library/prefabs/panel_prefab.json @@ -0,0 +1,12 @@ +{ + "prototype" : "sprite_prefab.json", + "components" : { + "named" : { + "name" : "panel" + }, + "sprite_renderer" : { + "mode" : "sliced", + "sprite" : "../sprites/panel_sprite.json" + } + } +} diff --git a/samples/bin/library/scenes/sample_09.json b/samples/bin/library/scenes/sample_09.json index fda74e0f..256bf5c4 100644 --- a/samples/bin/library/scenes/sample_09.json +++ b/samples/bin/library/scenes/sample_09.json @@ -5,60 +5,65 @@ },{ "prototype" : "../prefabs/camera_prefab.json" },{ - "prototype" : "../prefabs/layout_prefab.json", + "prototype" : "../prefabs/panel_prefab.json", "components" : { - "actor" : { - "translation" : [-250,0] - }, - "layout" : { - "size" : [500,200], - "halign" : "space_evenly" + "sprite_renderer" : { + "scale" : [4,2] } }, "children" : [{ "prototype" : "../prefabs/layout_prefab.json", "components" : { "layout" : { - "size" : [66,113] + "size" : [400,200], + "halign" : "space_evenly" } }, "children" : [{ - "prototype" : "../prefabs/ship_prefab.json", + "prototype" : "../prefabs/layout_prefab.json", "components" : { - "actor" : { - "translation" : [33,56.5] + "layout" : { + "size" : [66,113] } - } - }] - },{ - "prototype" : "../prefabs/layout_prefab.json", - "components" : { - "layout" : { - "size" : [66,113] - } - }, - "children" : [{ - "prototype" : "../prefabs/ship_prefab.json", + }, + "children" : [{ + "prototype" : "../prefabs/ship_prefab.json", + "components" : { + "actor" : { + "translation" : [33,56.5] + } + } + }] + },{ + "prototype" : "../prefabs/layout_prefab.json", "components" : { - "actor" : { - "translation" : [33,56.5] + "layout" : { + "size" : [66,113] } - } - }] - },{ - "prototype" : "../prefabs/layout_prefab.json", - "components" : { - "layout" : { - "size" : [66,113] - } - }, - "children" : [{ - "prototype" : "../prefabs/ship_prefab.json", + }, + "children" : [{ + "prototype" : "../prefabs/ship_prefab.json", + "components" : { + "actor" : { + "translation" : [33,56.5] + } + } + }] + },{ + "prototype" : "../prefabs/layout_prefab.json", "components" : { - "actor" : { - "translation" : [33,56.5] + "layout" : { + "size" : [66,113] } - } + }, + "children" : [{ + "prototype" : "../prefabs/ship_prefab.json", + "components" : { + "actor" : { + "translation" : [33,56.5] + } + } + }] }] }] }] diff --git a/samples/bin/library/sprites/panel.png b/samples/bin/library/sprites/panel.png new file mode 100644 index 00000000..9c301cc4 --- /dev/null +++ b/samples/bin/library/sprites/panel.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ebc16b176a3982ee84be2ad86a3d0ceb5790479c90394e183a9a2b8e9c7bc6a +size 625 diff --git a/samples/bin/library/sprites/panel_sprite.json b/samples/bin/library/sprites/panel_sprite.json new file mode 100644 index 00000000..2b0b1cbd --- /dev/null +++ b/samples/bin/library/sprites/panel_sprite.json @@ -0,0 +1,6 @@ +{ + "texture" : "panel.png", + "pivot" : { "x" : 0, "y" : 0 }, + "inner_texrect" : { "x" : 6, "y" : 6, "w" : 88, "h" : 88 }, + "outer_texrect" : { "x" : 0, "y" : 0, "w" : 100, "h" : 100 } +} diff --git a/sources/enduro2d/high/components/sprite_renderer.cpp b/sources/enduro2d/high/components/sprite_renderer.cpp index 04882369..b144e2e8 100644 --- a/sources/enduro2d/high/components/sprite_renderer.cpp +++ b/sources/enduro2d/high/components/sprite_renderer.cpp @@ -242,9 +242,14 @@ namespace e2d { if ( const sprite_asset::ptr& spr_a = c->sprite() ) { const sprite& spr = spr_a->content(); + + const b2f& outer_r = spr.outer_texrect(); + const v2f size = outer_r.size * c->scale(); + const v2f poff = (outer_r.position - spr.pivot()) * c->scale(); + ctx.draw_wire_rect( - spr.outer_texrect().position - spr.pivot() + spr.outer_texrect().size * 0.5f, - spr.outer_texrect().size, + poff + size * 0.5f, + size, ctx.selected() ? color32::yellow() : color32::magenta()); } } 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 96408152..73e74ba9 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 @@ -443,36 +443,6 @@ namespace e2d::render_system_impl return; } - const b2f& tex_r = spr.outer_texrect(); - const v2f& tex_s = tex_p->size().cast_to(); - - const f32 sw = tex_r.size.x; - const f32 sh = tex_r.size.y; - - const f32 px = tex_r.position.x - spr.pivot().x; - const f32 py = tex_r.position.y - spr.pivot().y; - - const v4f p1{px + 0.f, py + 0.f, 0.f, 1.f}; - const v4f p2{px + sw, py + 0.f, 0.f, 1.f}; - const v4f p3{px + sw, py + sh, 0.f, 1.f}; - const v4f p4{px + 0.f, py + sh, 0.f, 1.f}; - - const f32 tx = tex_r.position.x / tex_s.x; - const f32 ty = tex_r.position.y / tex_s.y; - const f32 tw = tex_r.size.x / tex_s.x; - const f32 th = tex_r.size.y / tex_s.y; - - const color32& tc = spr_r.tint(); - - const batcher_type::index_type indices[] = { - 0u, 1u, 2u, 2u, 3u, 0u}; - - const batcher_type::vertex_type vertices[] = { - { v3f(p1 * model_m), {tx + 0.f, ty + 0.f}, tc }, - { v3f(p2 * model_m), {tx + tw, ty + 0.f}, tc }, - { v3f(p3 * model_m), {tx + tw, ty + th }, tc }, - { v3f(p4 * model_m), {tx + 0.f, ty + th }, tc }}; - const render::sampler_min_filter tex_min_f = spr_r.filtering() ? render::sampler_min_filter::linear : render::sampler_min_filter::nearest; @@ -496,7 +466,7 @@ namespace e2d::render_system_impl mat_a = spr_r.find_material(screen_material_hash); break; default: - E2D_ASSERT_MSG(false, "unexpected blend mode for sprite"); + E2D_ASSERT_MSG(false, "unexpected sprite blending"); break; } @@ -514,11 +484,144 @@ namespace e2d::render_system_impl .filter(tex_min_f, tex_mag_f)) .merge(node_r.properties()); - batcher_.batch( - mat_a, - property_cache_, - indices, std::size(indices), - vertices, std::size(vertices)); + if ( spr_r.mode() == sprite_renderer::modes::simple ) { + + // 2 -------- 3 + // | | + // | | + // | | + // 0 -------- 1 + + const v2f& tex_s = tex_p->size().cast_to(); + const b2f& outer_r = spr.outer_texrect(); + + const v2f size = outer_r.size * spr_r.scale(); + const v2f poff = (outer_r.position - spr.pivot()) * spr_r.scale(); + + const v2f pos_xs = v2f{ + 0.f, size.x} + poff.x; + + const v2f pos_ys = v2f{ + 0.f, size.y} + poff.y; + + const v2f tex_xs = v2f{ + outer_r.position.x, + outer_r.position.x + outer_r.size.x} / tex_s.x; + + const v2f tex_ys = v2f{ + outer_r.position.y, + outer_r.position.y + outer_r.size.y} / tex_s.y; + + const color32& tc = spr_r.tint(); + + const batcher_type::index_type indices[] = { + 0, 1, 3, 3, 2, 0, + }; + + const batcher_type::vertex_type vertices[] = { + { v3f{v4f{pos_xs[0], pos_ys[0], 0.f, 1.f} * model_m}, v2f{tex_xs[0], tex_ys[0]}, tc }, + { v3f{v4f{pos_xs[1], pos_ys[0], 0.f, 1.f} * model_m}, v2f{tex_xs[1], tex_ys[0]}, tc }, + { v3f{v4f{pos_xs[0], pos_ys[1], 0.f, 1.f} * model_m}, v2f{tex_xs[0], tex_ys[1]}, tc }, + { v3f{v4f{pos_xs[1], pos_ys[1], 0.f, 1.f} * model_m}, v2f{tex_xs[1], tex_ys[1]}, tc }, + }; + + batcher_.batch( + mat_a, + property_cache_, + indices, std::size(indices), + vertices, std::size(vertices)); + } else if ( spr_r.mode() == sprite_renderer::modes::sliced ) { + + // 12 13 ********* 14 15 + // _8 _9 --------- 10 11 + // | * * | + // | * * | + // | * * | + // _4 _5 ********* _6 _7 + // _0 _1 --------- _2 _3 + + const v2f& tex_s = tex_p->size().cast_to(); + const b2f& inner_r = spr.inner_texrect(); + const b2f& outer_r = spr.outer_texrect(); + + const f32 left = inner_r.position.x - outer_r.position.x; + const f32 right = (outer_r.size.x - inner_r.size.x) - left; + const f32 bottom = inner_r.position.y - outer_r.position.y; + const f32 top = (outer_r.size.y - inner_r.size.y) - bottom; + + const v2f size = outer_r.size * spr_r.scale(); + const v2f poff = (outer_r.position - spr.pivot()) * spr_r.scale(); + + const v4f pos_xs = v4f{ + 0.f, + left, + size.x - right, + size.x} + poff.x; + + const v4f pos_ys = v4f{ + 0.f, + bottom, + size.y - top, + size.y} + poff.y; + + const v4f tex_xs = v4f{ + outer_r.position.x, + inner_r.position.x, + inner_r.position.x + inner_r.size.x, + outer_r.position.x + outer_r.size.x} / tex_s.x; + + const v4f tex_ys = v4f{ + outer_r.position.y, + inner_r.position.y, + inner_r.position.y + inner_r.size.y, + outer_r.position.y + outer_r.size.y} / tex_s.y; + + const color32& tc = spr_r.tint(); + + const batcher_type::index_type indices[] = { + 0, 1, 5, 5, 4, 0, + 1, 2, 6, 6, 5, 1, + 2, 3, 7, 7, 6, 2, + + 4, 5, 9, 9, 8, 4, + 5, 6, 10, 10, 9, 5, + 6, 7, 11, 11, 10, 6, + + 8, 9, 13, 13, 12, 8, + 9, 10, 14, 14, 13, 9, + 10, 11, 15, 15, 14, 10, + }; + + const batcher_type::vertex_type vertices[] = { + { v3f{v4f{pos_xs[0], pos_ys[0], 0.f, 1.f} * model_m}, v2f{tex_xs[0], tex_ys[0]}, tc }, + { v3f{v4f{pos_xs[1], pos_ys[0], 0.f, 1.f} * model_m}, v2f{tex_xs[1], tex_ys[0]}, tc }, + { v3f{v4f{pos_xs[2], pos_ys[0], 0.f, 1.f} * model_m}, v2f{tex_xs[2], tex_ys[0]}, tc }, + { v3f{v4f{pos_xs[3], pos_ys[0], 0.f, 1.f} * model_m}, v2f{tex_xs[3], tex_ys[0]}, tc }, + + { v3f{v4f{pos_xs[0], pos_ys[1], 0.f, 1.f} * model_m}, v2f{tex_xs[0], tex_ys[1]}, tc }, + { v3f{v4f{pos_xs[1], pos_ys[1], 0.f, 1.f} * model_m}, v2f{tex_xs[1], tex_ys[1]}, tc }, + { v3f{v4f{pos_xs[2], pos_ys[1], 0.f, 1.f} * model_m}, v2f{tex_xs[2], tex_ys[1]}, tc }, + { v3f{v4f{pos_xs[3], pos_ys[1], 0.f, 1.f} * model_m}, v2f{tex_xs[3], tex_ys[1]}, tc }, + + { v3f{v4f{pos_xs[0], pos_ys[2], 0.f, 1.f} * model_m}, v2f{tex_xs[0], tex_ys[2]}, tc }, + { v3f{v4f{pos_xs[1], pos_ys[2], 0.f, 1.f} * model_m}, v2f{tex_xs[1], tex_ys[2]}, tc }, + { v3f{v4f{pos_xs[2], pos_ys[2], 0.f, 1.f} * model_m}, v2f{tex_xs[2], tex_ys[2]}, tc }, + { v3f{v4f{pos_xs[3], pos_ys[2], 0.f, 1.f} * model_m}, v2f{tex_xs[3], tex_ys[2]}, tc }, + + { v3f{v4f{pos_xs[0], pos_ys[3], 0.f, 1.f} * model_m}, v2f{tex_xs[0], tex_ys[3]}, tc }, + { v3f{v4f{pos_xs[1], pos_ys[3], 0.f, 1.f} * model_m}, v2f{tex_xs[1], tex_ys[3]}, tc }, + { v3f{v4f{pos_xs[2], pos_ys[3], 0.f, 1.f} * model_m}, v2f{tex_xs[2], tex_ys[3]}, tc }, + { v3f{v4f{pos_xs[3], pos_ys[3], 0.f, 1.f} * model_m}, v2f{tex_xs[3], tex_ys[3]}, tc }, + }; + + batcher_.batch( + mat_a, + property_cache_, + indices, std::size(indices), + vertices, std::size(vertices)); + } else { + E2D_ASSERT_MSG(false, "unexpected sprite mode"); + } } //