neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
texture_atlas.hpp
Go to the documentation of this file.
1// texture_atlas.hpp
2/*
3 neogfx C++ App/Game Engine
4 Copyright (c) 2015, 2020 Leigh Johnston. All Rights Reserved.
5
6 This program is free software: you can redistribute it and / or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#pragma once
21
22#include <neogfx/neogfx.hpp>
23#include <unordered_map>
24#include <set>
25#include <tuple>
26#include "i_texture_atlas.hpp"
27#include "i_texture_manager.hpp"
28#include "texture.hpp"
29#include "sub_texture.hpp"
30#include "rect_pack.hpp"
31
32namespace neogfx
33{
34 class i_native_texture;
35
37 {
38 private:
39 struct fragments
40 {
42 {
43 bool operator()(const rect& aLhs, const rect& aRhs) const
44 {
45 return std::forward_as_tuple(aLhs.width() * aLhs.height(), aLhs.top_left()) <
46 std::forward_as_tuple(aRhs.width() * aRhs.height(), aRhs.top_left());
47 }
48 };
49 rect_pack pack;
50 std::set<rect, fragment_less_than> used;
51 std::set<rect, fragment_less_than> freed; // todo: use this when bin pack is full
52 bool insert(const size& aSize, rect& aResult)
53 {
54 if (pack.insert(aSize, aResult))
55 {
56 used.insert(aResult);
57 return true;
58 }
59 else
60 return false;
61 }
62 };
63 typedef std::pair<texture, fragments> page;
64 typedef std::list<page> pages;
65 typedef std::pair<pages::iterator, neogfx::sub_texture> entry;
66 typedef std::unordered_map<texture_id, entry> entries;
67 public:
68 texture_atlas(const size& aPageSize);
69 public:
70 const i_sub_texture& sub_texture(texture_id aSubTextureId) const override;
71 i_sub_texture& sub_texture(texture_id aSubTextureId) override;
72 i_sub_texture& create_sub_texture(const size& aSize, dimension aDpiScaleFactor, texture_sampling aSampling, texture_data_format aDataFormat = texture_data_format::RGBA) override;
73 i_sub_texture& create_sub_texture(const i_image& aImage) override;
74 i_sub_texture& create_sub_texture(const i_image& aImage, const rect& aImagePart) override;
75 void destroy_sub_texture(i_sub_texture& aSubTexture) override;
76 private:
77 const size& page_size() const;
78 pages::iterator create_page(dimension aDpiScaleFactor, texture_sampling aSampling, texture_data_format aDataFormat);
79 std::pair<pages::iterator, rect> allocate_space(const size& aSize, dimension aDpiScaleFactor, texture_sampling aSampling, texture_data_format aDataFormat);
80 private:
81 i_texture_manager& iTextureManager;
82 size iPageSize;
83 pages iPages;
84 entries iEntries;
85 };
86}
point_type top_left() const
dimension_type height() const
dimension_type width() const
bool insert(const size &aElementSize, rect &aResult)
i_sub_texture & sub_texture(texture_id aSubTextureId) override
i_sub_texture & create_sub_texture(const i_image &aImage) override
void destroy_sub_texture(i_sub_texture &aSubTexture) override
i_sub_texture & create_sub_texture(const size &aSize, dimension aDpiScaleFactor, texture_sampling aSampling, texture_data_format aDataFormat=texture_data_format::RGBA) override
i_sub_texture & create_sub_texture(const i_image &aImage, const rect &aImagePart) override
const i_sub_texture & sub_texture(texture_id aSubTextureId) const override
texture_atlas(const size &aPageSize)
default_geometry_value_type dimension
game::id_t texture_id
Definition i_texture.hpp:30
texture_data_format
Definition i_texture.hpp:56
texture_sampling
Definition i_texture.hpp:42
bool operator()(const rect &aLhs, const rect &aRhs) const