galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
TextureArray.cpp
Go to the documentation of this file.
1
7
8#include <stb_image.h>
9
11#include "galaxy/core/ServiceLocator.hpp"
13
14#include "TextureArray.hpp"
15
16namespace galaxy
17{
18 namespace graphics
19 {
21 : Texture {}
22 {
23 glCreateTextures(GL_TEXTURE_2D_ARRAY, 1, &m_id);
24 }
25
27 : Texture {std::move(t)}
28 {
29 }
30
32 {
33 if (this != &t)
34 {
35 Texture::operator=(std::move(t));
36 }
37
38 return *this;
39 }
40
42 {
43 if (!m_data.empty())
44 {
45 for (unsigned char* data : m_data)
46 {
47 stbi_image_free(data);
48 }
49 }
50 }
51
52 bool TextureArray::add(const std::string& file)
53 {
54 auto& fs = core::ServiceLocator<fs::VirtualFileSystem>::ref();
55
56 auto data = fs.read_binary(file);
57 if (!data.empty())
58 {
59 stbi_set_flip_vertically_on_load(true);
60 m_data.emplace_back(stbi_load_from_memory(data.data(), static_cast<int>(data.size() * sizeof(std::uint8_t)), nullptr, nullptr, nullptr, STBI_rgb_alpha));
61 }
62 else
63 {
64 GALAXY_LOG(GALAXY_ERROR, "Failed to read '{0}' from vfs.", file);
65 }
66
67 return false;
68 }
69
70 void TextureArray::build(const int width, const int height)
71 {
72 if (!m_data.empty())
73 {
74 auto& config = core::ServiceLocator<core::Config>::ref();
75
76 m_width = width;
78
79 glTextureStorage3D(m_id, 1, GL_RGBA8, m_width, m_height, static_cast<GLsizei>(m_data.size()));
80
81 for (auto i = 0; i < m_data.size(); i++)
82 {
83 auto data = m_data[i];
84 if (data != nullptr)
85 {
86 glTextureSubImage3D(m_id, 0, 0, 0, i, m_width, m_height, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
87 stbi_image_free(data);
88 }
89 }
90
91 m_data = {};
92
93 glGenerateTextureMipmap(m_id);
94
95 if (config.get<int>("trilinear_filtering", "graphics"))
96 {
98 }
99 else
100 {
102 }
103
105 anisotropy(config.get<int>("ansiotrophic_filtering", "graphics"));
106 }
107 else
108 {
109 GALAXY_LOG(GALAXY_WARNING, "Tried to build an empty texture array.");
110 }
111 }
112
113 bool TextureArray::build_from_tileset(const std::string& file, const int tile_size)
114 {
115 auto result = true;
116
117 auto& fs = core::ServiceLocator<fs::VirtualFileSystem>::ref();
118 auto& config = core::ServiceLocator<core::Config>::ref();
119
120 auto buffer = fs.read_binary(file);
121 if (!buffer.empty())
122 {
123 stbi_set_flip_vertically_on_load(true);
124 unsigned char* data = stbi_load_from_memory(buffer.data(), static_cast<int>(buffer.size() * sizeof(std::uint8_t)), &m_width, &m_height, nullptr, STBI_rgb_alpha);
125
126 if (data)
127 {
128 const auto tiles_x = m_width / tile_size;
129 const auto tiles_y = m_height / tile_size;
130 const auto tile_count = tiles_x * tiles_y;
131
132 glTextureStorage3D(m_id, 1, GL_RGBA8, tile_size, tile_size, tile_count);
133
134 unsigned int tilesheet = 0;
135 glCreateTextures(GL_TEXTURE_2D, 1, &tilesheet);
136 glTextureStorage2D(tilesheet, 1, GL_RGBA8, m_width, m_height);
137 glTextureSubImage2D(tilesheet, 0, 0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
138
139 for (auto i = 0; i < tile_count; ++i)
140 {
141 const auto x = (i % tiles_x) * tile_size;
142 const auto y = (i / tiles_x) * tile_size;
143
144 glCopyImageSubData(tilesheet, GL_TEXTURE_2D, 0, x, y, 0, m_id, GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, tile_size, tile_size, 1);
145 }
146
147 glDeleteTextures(1, &tilesheet);
148 glGenerateTextureMipmap(m_id);
149
150 if (config.get<int>("trilinear_filtering", "graphics"))
151 {
153 }
154 else
155 {
157 }
158
160 anisotropy(config.get<int>("ansiotrophic_filtering", "graphics"));
161 }
162 else
163 {
164 GALAXY_LOG(GALAXY_ERROR, "Failed to load texture from memory because '{0}'.", stbi_failure_reason());
165 result = false;
166 }
167
168 stbi_image_free(data);
169 }
170 else
171 {
172 GALAXY_LOG(GALAXY_ERROR, "Failed to read '{0}' from vfs.", file);
173 result = false;
174 }
175
176 return result;
177 }
178
180 {
181 glBindTexture(GL_TEXTURE_2D_ARRAY, m_id);
182 }
183
185 {
186 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
187 }
188 } // namespace graphics
189} // namespace galaxy
#define GALAXY_LOG(level, msg,...)
Definition Log.hpp:28
#define GALAXY_ERROR
Definition Log.hpp:24
void unbind() override
Deactivate context.
bool add(const std::string &file)
Add a texture to the texture array.
meta::vector< unsigned char * > m_data
Data from adding a file to the texture array. Not kept after building.
void bind() override
Activate context.
void build(const int width, const int height)
Creates the array texture.
TextureArray & operator=(TextureArray &&)
Move assignment operator.
bool build_from_tileset(const std::string &file, const int tile_size)
Creates an array texture from a tileset.
virtual ~TextureArray()
Destructor.
OpenGL 2D Texture.
Definition Texture.hpp:26
int m_height
Cached height.
Definition Texture.hpp:171
int anisotropy() const
Get current anisotropy level.
Definition Texture.cpp:152
float width() const
Get texture width.
Definition Texture.cpp:157
unsigned int m_id
OpenGL id.
Definition Texture.hpp:161
Texture & operator=(Texture &&)
Move assignment operator.
Definition Texture.cpp:49
int m_width
Cached width.
Definition Texture.hpp:166
float height() const
Get texture height.
Definition Texture.cpp:162
TextureMode mode() const
Get texture mode.
Definition Texture.cpp:97
TextureFilter filter() const
Get texture filter.
Definition Texture.cpp:120
@ NEAREST
Nearest-neighbour.
@ CLAMP_TO_EDGE
GL_CLAMP_TO_EDGE.
Animated.cpp galaxy.
Definition Animated.cpp:16
STL namespace.