/
TextureAtlas.h
159 lines (116 loc) · 3.78 KB
/
TextureAtlas.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef TEXTURE_ATLAS_H
#define TEXTURE_ATLAS_H
#include <string>
#include <vector>
#include "System/creg/creg_cond.h"
#include "System/float4.h"
#include "System/type2.h"
#include "System/UnorderedMap.hpp"
class IAtlasAllocator;
/** @brief texture coordinates of an atlas subimage. */
//typedef float4 AtlasedTexture;
struct AtlasedTexture : public float4
{
AtlasedTexture() : float4() {}
AtlasedTexture(const float4& f) : float4(f) {}
CR_DECLARE_STRUCT(AtlasedTexture)
};
/** @brief Class for combining multiple bitmaps into one large single bitmap. */
class CTextureAtlas
{
public:
enum TextureType {
RGBA32
};
enum {
ATLAS_ALLOC_LEGACY = 0,
ATLAS_ALLOC_QUADTREE = 1,
};
public:
CTextureAtlas(unsigned int allocType = ATLAS_ALLOC_LEGACY);
~CTextureAtlas();
// add a texture from a memory pointer
size_t AddTexFromMem(std::string name, int xsize, int ysize, TextureType texType, void* data);
// add a texture from a file
size_t AddTexFromFile(std::string name, std::string file);
// add a blank texture
size_t AddTex(std::string name, int xsize, int ysize, TextureType texType = RGBA32);
void* AddGetTex(std::string name, int xsize, int ysize, TextureType texType = RGBA32) {
const size_t idx = AddTex(std::move(name), xsize, ysize, texType);
MemTex& tex = memTextures[idx];
auto& mem = tex.mem;
return (mem.data());
}
/**
* Creates the atlas containing all the specified textures.
* @return true if suceeded, false if not all textures did fit
* into the specified maxsize.
*/
bool Finalize();
/**
* @return a boolean true if the texture exists within
* the "textures" map and false if it does not.
*/
bool TextureExists(const std::string& name);
//! @return reference to the Texture struct of the specified texture
AtlasedTexture& GetTexture(const std::string& name);
// NOTE: safe with unordered_map after atlas has been finalized
AtlasedTexture* GetTexturePtr(const std::string& name) { return &GetTexture(name); }
/**
* @return a Texture struct of the specified texture if it exists,
* otherwise return a backup texture.
*/
AtlasedTexture& GetTextureWithBackup(const std::string& name, const std::string& backupName);
IAtlasAllocator* GetAllocator() { return atlasAllocator; }
int2 GetSize() const;
std::string GetName() const { return name; }
unsigned int GetTexID() const { return atlasTexID; }
void BindTexture();
void SetFreeTexture(bool b) { freeTexture = b; }
void SetName(const std::string& s) { name = s; }
static void SetDebug(bool b) { debug = b; }
static bool GetDebug() { return debug; }
protected:
int GetBPP(TextureType texType) const {
switch (texType) {
case RGBA32: return 32;
default: return 32;
}
}
bool CreateTexture();
protected:
IAtlasAllocator* atlasAllocator = nullptr;
struct MemTex {
public:
MemTex(): xsize(0), ysize(0), texType(RGBA32) {}
MemTex(const MemTex&) = delete;
MemTex(MemTex&& t) { *this = std::move(t); }
MemTex& operator = (const MemTex&) = delete;
MemTex& operator = (MemTex&& t) {
xsize = t.xsize;
ysize = t.ysize;
texType = t.texType;
names = std::move(t.names);
mem = std::move(t.mem);
return *this;
}
public:
int xsize;
int ysize;
TextureType texType;
std::vector<std::string> names;
std::vector<char> mem;
};
std::string name;
// temporary storage of all textures
std::vector<MemTex> memTextures;
spring::unordered_map<std::string, size_t> files;
spring::unordered_map<std::string, AtlasedTexture> textures;
unsigned int atlasTexID = 0;
bool initialized = false;
bool freeTexture = true; // free texture on atlas destruction?
// set to true to write finalized texture atlas to disk
static bool debug;
};
#endif // TEXTURE_ATLAS_H