/
Mr.Stalin
/
FOnline-Engine
Обзор
Документация
Войти
/
Mr.Stalin
/
FOnline-Engine
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Source/Client/DefaultSprites.h
162 строки
7 KB
cvet
Enhance AtlasSprite region handling and rendering
21 июл 2026, 22:31
21 июл 2026, 22:31
c73a04c
Код
Авторство
О чём код?
// __________ ___ ______ _ // / ____/ __ \____ / (_)___ ___ / ____/___ ____ _(_)___ ___ // / /_ / / / / __ \/ / / __ \/ _ \ / __/ / __ \/ __ `/ / __ \/ _ ` // / __/ / /_/ / / / / / / / / / __/ / /___/ / / / /_/ / / / / / __/ // /_/ \____/_/ /_/_/_/_/ /_/\___/ /_____/_/ /_/\__, /_/_/ /_/\___/ // /____/ // FOnline Engine // https://fonline.ru // https://github.com/cvet/fonline // // MIT License // // Copyright (c) 2006 - 2026, Anton Tsvetinskiy aka cvet <cvet@tut.by> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // #pragma once #include "Common.h" #include "Rendering.h" #include "SpriteManager.h" #include "SpriteResource.h" FO_BEGIN_NAMESPACE struct AtlasSpriteRegion { frect32 DrawRect {}; frect32 TextureRect {}; }; class AtlasSprite : public Sprite { public: explicit AtlasSprite(ptr<SpriteManager> spr_mngr, isize32 size, ipos32 offset, nptr<TextureAtlas> atlas, unique_del_nptr<TextureAtlasLayout::Allocation> atlas_allocation, frect32 atlas_rect, vector<bool>&& hit_data, optional<SpriteMeshData> mesh_data = std::nullopt); AtlasSprite(const AtlasSprite&) = delete; AtlasSprite(AtlasSprite&& other) noexcept; auto operator=(const AtlasSprite&) = delete; auto operator=(AtlasSprite&&) noexcept -> AtlasSprite& = delete; ~AtlasSprite() override; [[nodiscard]] auto IsHitTest(ipos32 pos) const -> bool override; [[nodiscard]] auto GetAtlas() const -> nptr<const TextureAtlas> { return _atlas; } [[nodiscard]] auto GetAtlas() -> nptr<TextureAtlas> { return _atlas; } [[nodiscard]] auto GetBatchTexture() const -> nptr<const RenderTexture> override; [[nodiscard]] auto IsCopyable() const -> bool override { return true; } [[nodiscard]] auto MakeCopy() const -> shared_ptr<Sprite> override; [[nodiscard]] auto GetAtlasRect() const noexcept -> frect32 { return _atlasRect; } [[nodiscard]] auto ResolveRegion(fpos32 uv0, fpos32 uv1, const frect32& pos) const -> optional<AtlasSpriteRegion>; auto FillData(ptr<RenderDrawBuffer> dbuf, const frect32& pos, const tuple<ucolor, ucolor>& colors) const -> size_t override; auto FillRegionData(ptr<RenderDrawBuffer> dbuf, fpos32 uv0, fpos32 uv1, const frect32& pos, ucolor color) const -> size_t; protected: nptr<TextureAtlas> _atlas {}; frect32 _atlasRect {}; vector<bool> _hitTestData {}; optional<SpriteMeshData> _meshData {}; unique_del_nptr<TextureAtlasLayout::Allocation> _atlasAllocation {}; }; class SpriteSheet final : public Sprite { friend class DefaultSpriteFactory; friend class ResourceManager; public: SpriteSheet(ptr<SpriteManager> spr_mngr, int32_t frames, int32_t ticks, int32_t dirs); SpriteSheet(const SpriteSheet&) = delete; SpriteSheet(SpriteSheet&&) noexcept = default; auto operator=(const SpriteSheet&) = delete; auto operator=(SpriteSheet&&) noexcept -> SpriteSheet& = delete; ~SpriteSheet() override = default; [[nodiscard]] auto IsHitTest(ipos32 pos) const -> bool override; [[nodiscard]] auto GetBatchTexture() const -> nptr<const RenderTexture> override; [[nodiscard]] auto IsCopyable() const -> bool override { return true; } [[nodiscard]] auto MakeCopy() const -> shared_ptr<Sprite> override; [[nodiscard]] auto GetCurSpr() const -> ptr<const Sprite>; [[nodiscard]] auto GetCurSpr() -> ptr<Sprite>; [[nodiscard]] auto GetSpr(int32_t num_frm) const -> ptr<const Sprite>; [[nodiscard]] auto GetSpr(int32_t num_frm) -> ptr<Sprite>; [[nodiscard]] auto GetDir(mdir dir) const -> nptr<const SpriteSheet>; [[nodiscard]] auto GetDir(mdir dir) -> nptr<SpriteSheet>; [[nodiscard]] auto IsPlaying() const -> bool override { return _playing; } [[nodiscard]] auto GetTime() const -> float32_t override; [[nodiscard]] auto GetWholeTicks() const noexcept -> int32_t { return _wholeTicks; } [[nodiscard]] auto GetFramesCount() const noexcept -> int32_t { return _framesCount; } [[nodiscard]] auto GetStateAnim() const noexcept -> CritterStateAnim { return _stateAnim; } [[nodiscard]] auto GetActionAnim() const noexcept -> CritterActionAnim { return _actionAnim; } [[nodiscard]] auto GetDirCount() const noexcept -> int32_t { return _dirCount; } [[nodiscard]] auto GetSprOffset() const noexcept -> const_span<ipos32> { return _sprOffset; } auto FillData(ptr<RenderDrawBuffer> dbuf, const frect32& pos, const tuple<ucolor, ucolor>& colors) const -> size_t override; void Prewarm() override; void SetTime(float32_t normalized_time) override; void SetDir(mdir dir) override; void Play(hstring anim_name, bool looped, bool reversed) override; void Stop() override; auto Update() -> bool override; private: void RefreshParams(); vector<shared_ptr<Sprite>> _spr {}; vector<ipos32> _sprOffset {}; int32_t _framesCount {}; int32_t _wholeTicks {}; CritterStateAnim _stateAnim {}; CritterActionAnim _actionAnim {}; int32_t _dirCount {}; shared_ptr<SpriteSheet> _dirs[GameSettings::MAP_DIR_COUNT - 1] {}; hdir _curDir {}; int32_t _curIndex {}; bool _playing {}; bool _looped {}; bool _reversed {}; nanotime _startTick {}; }; class DefaultSpriteFactory : public SpriteFactory { public: explicit DefaultSpriteFactory(ptr<SpriteManager> spr_mngr); DefaultSpriteFactory(const DefaultSpriteFactory&) = delete; DefaultSpriteFactory(DefaultSpriteFactory&&) noexcept = default; auto operator=(const DefaultSpriteFactory&) = delete; auto operator=(DefaultSpriteFactory&&) noexcept -> DefaultSpriteFactory& = delete; ~DefaultSpriteFactory() override = default; [[nodiscard]] auto GetExtensions() const -> vector<string> override { return {"fofrm", "frm", "fr0", "rix", "art", "zar", "til", "mos", "bam", "png", "tga"}; } auto LoadSprite(hstring path, AtlasType atlas_type) -> shared_ptr<Sprite> override; auto LoadSpriteAsQuad(hstring path, AtlasType atlas_type) -> shared_ptr<AtlasSprite>; private: auto FillAtlas(AtlasType atlas_type, isize32 size, ipos32 offset, nptr<const ucolor> pixels, optional<SpriteMeshData> mesh_data) -> shared_ptr<AtlasSprite>; ptr<SpriteManager> _sprMngr; vector<ucolor> _borderBuf {}; }; FO_END_NAMESPACE