Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_TERRAINTEXTUREMANAGER
19 : #define INCLUDED_TERRAINTEXTUREMANAGER
20 :
21 : #include "lib/file/vfs/vfs_path.h"
22 : #include "ps/CStr.h"
23 : #include "ps/Singleton.h"
24 : #include "renderer/backend/IDeviceCommandContext.h"
25 : #include "renderer/backend/ITexture.h"
26 :
27 : #include <map>
28 : #include <memory>
29 : #include <vector>
30 :
31 : // access to sole CTerrainTextureManager object
32 : #define g_TexMan CTerrainTextureManager::GetSingleton()
33 :
34 : #define NUM_ALPHA_MAPS 14
35 :
36 : class CTerrainTextureEntry;
37 : class CTerrainProperties;
38 :
39 : typedef std::shared_ptr<CTerrainProperties> CTerrainPropertiesPtr;
40 :
41 0 : class CTerrainGroup
42 : {
43 : // name of this terrain group (as specified by the terrain XML)
44 : CStr m_Name;
45 : // "index".. basically a bogus integer that can be used by ScEd to set texture
46 : // priorities
47 : size_t m_Index;
48 : // list of textures of this type (found from the texture directory)
49 : std::vector<CTerrainTextureEntry*> m_Terrains;
50 :
51 : public:
52 0 : CTerrainGroup(CStr name, size_t index):
53 : m_Name(name),
54 0 : m_Index(index)
55 0 : {}
56 :
57 : // Add a texture entry to this terrain type
58 : void AddTerrain(CTerrainTextureEntry*);
59 : // Remove a texture entry
60 : void RemoveTerrain(CTerrainTextureEntry*);
61 :
62 : size_t GetIndex() const
63 : { return m_Index; }
64 : CStr GetName() const
65 : { return m_Name; }
66 :
67 0 : const std::vector<CTerrainTextureEntry*> &GetTerrains() const
68 0 : { return m_Terrains; }
69 : };
70 :
71 :
72 0 : struct TerrainAlpha
73 : {
74 : // Composite alpha map (all the alpha maps packed into one texture).
75 : std::unique_ptr<Renderer::Backend::ITexture> m_CompositeAlphaMap;
76 : // Data is used to separate file loading and uploading to GPU.
77 : std::shared_ptr<u8> m_CompositeDataToUpload;
78 : // Coordinates of each (untransformed) alpha map within the packed texture.
79 : struct
80 : {
81 : float u0, u1, v0, v1;
82 : } m_AlphaMapCoords[NUM_ALPHA_MAPS];
83 : };
84 :
85 :
86 : ///////////////////////////////////////////////////////////////////////////////////////////
87 : // CTerrainTextureManager : manager class for all terrain texture objects
88 : class CTerrainTextureManager : public Singleton<CTerrainTextureManager>
89 : {
90 : friend class CTerrainTextureEntry;
91 :
92 : public:
93 : using TerrainGroupMap = std::map<CStr, CTerrainGroup*>;
94 : using TerrainAlphaMap = std::map<VfsPath, TerrainAlpha>;
95 :
96 : // constructor, destructor
97 : CTerrainTextureManager();
98 : ~CTerrainTextureManager();
99 :
100 : // Find all XML's in the directory (with subdirs) and try to load them as
101 : // terrain XML's
102 : int LoadTerrainTextures();
103 :
104 : void UnloadTerrainTextures();
105 :
106 : CTerrainTextureEntry* FindTexture(const CStr& tag) const;
107 :
108 : // Create a texture object for a new terrain texture at path, using the
109 : // property sheet props.
110 : CTerrainTextureEntry* AddTexture(const CTerrainPropertiesPtr& props, const VfsPath& path);
111 :
112 : // Remove the texture from all our maps and lists and delete it afterwards.
113 : void DeleteTexture(CTerrainTextureEntry* entry);
114 :
115 : // Find or create a new texture group. All terrain groups are owned by the
116 : // texturemanager (TerrainTypeManager)
117 : CTerrainGroup* FindGroup(const CStr& name);
118 :
119 0 : const TerrainGroupMap& GetGroups() const
120 0 : { return m_TerrainGroups; }
121 :
122 : CTerrainTextureManager::TerrainAlphaMap::iterator LoadAlphaMap(const VfsPath& alphaMapType);
123 :
124 : void UploadResourcesIfNeeded(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
125 :
126 : private:
127 : // All texture entries created by this class, for easy freeing now that
128 : // textures may be in several STextureType's
129 : std::vector<CTerrainTextureEntry*> m_TextureEntries;
130 :
131 : TerrainGroupMap m_TerrainGroups;
132 :
133 : TerrainAlphaMap m_TerrainAlphas;
134 :
135 : size_t m_LastGroupIndex;
136 :
137 : // A way to separate file loading and uploading to GPU to not stall uploading.
138 : // Once we get a properly threaded loading we might optimize that.
139 : std::vector<CTerrainTextureManager::TerrainAlphaMap::iterator> m_AlphaMapsToUpload;
140 : };
141 :
142 : #endif // INCLUDED_TERRAINTEXTUREMANAGER
|