MCPcopy Create free account
hub / github.com/OpenStarbound/OpenStarbound / addTexture

Method addTexture

source/application/StarTextureAtlas.hpp:146–205  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

144
145template <typename AtlasTextureHandle>
146auto TextureAtlasSet<AtlasTextureHandle>::addTexture(Image const& image, bool borderPixels) -> TextureHandle {
147 if (image.empty())
148 throw TextureAtlasException("Empty image given in TextureAtlasSet::addTexture");
149
150 Image finalImage;
151 if (borderPixels) {
152 Vec2U imageSize = image.size();
153 Vec2U finalImageSize = imageSize + Vec2U(2, 2);
154 finalImage = Image(finalImageSize, PixelFormat::RGBA32);
155
156 // Fill 1px border on all sides of the image
157 for (unsigned y = 0; y < finalImageSize[1]; ++y) {
158 for (unsigned x = 0; x < finalImageSize[0]; ++x) {
159 unsigned xind = clamp<unsigned>(x, 1, imageSize[0]) - 1;
160 unsigned yind = clamp<unsigned>(y, 1, imageSize[1]) - 1;
161 finalImage.set32(x, y, image.getrgb(xind, yind));
162 }
163 }
164 } else {
165 finalImage = image;
166 }
167
168 auto tryAtlas = [&](TextureAtlas* atlas) -> TextureHandle {
169 auto placement = addTextureToAtlas(atlas, finalImage, borderPixels);
170 if (!placement)
171 return nullptr;
172
173 auto textureEntry = make_shared<TextureEntry>();
174 textureEntry->textureImage = std::move(finalImage);
175 textureEntry->atlasPlacement = *placement;
176
177 m_textures.add(textureEntry);
178 sortAtlases();
179 return textureEntry;
180 };
181
182 // Try the first 'm_textureFitTries' atlases to see if we can fit a given
183 // texture in an existing atlas. Do this from the most full to the least
184 // full atlas to maximize compression.
185 size_t startAtlas = m_atlases.size() - min<size_t>(m_atlases.size(), m_textureFitTries);
186 for (size_t i = startAtlas; i < m_atlases.size(); ++i) {
187 if (auto texturePtr = tryAtlas(m_atlases[i].get()))
188 return texturePtr;
189 }
190
191 // If we have not found an existing atlas to put the texture, need to create
192 // a new atlas
193 m_atlases.append(make_shared<TextureAtlas>(TextureAtlas{
194 createAtlasTexture(Vec2U::filled(m_atlasCellSize * m_atlasNumCells), PixelFormat::RGBA32),
195 unique_ptr<bool[]>(new bool[m_atlasNumCells * m_atlasNumCells]()), 0
196 }));
197
198 if (auto texturePtr = tryAtlas(m_atlases.last().get()))
199 return texturePtr;
200
201 // If it can't fit in a brand new empty atlas, it will not fit in any atlas
202 destroyAtlasTexture(m_atlases.last()->atlasTexture);
203 m_atlases.removeLast();

Callers 1

createMethod · 0.80

Calls 10

ImageClass · 0.85
set32Method · 0.80
getrgbMethod · 0.60
emptyMethod · 0.45
sizeMethod · 0.45
addMethod · 0.45
getMethod · 0.45
appendMethod · 0.45
lastMethod · 0.45
removeLastMethod · 0.45

Tested by

no test coverage detected