Minor fixes
This commit is contained in:
parent
1ac992b5c7
commit
2622951144
|
|
@ -132,7 +132,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
auto& viewerComponent = viewer.get<Nz::CameraComponent>();
|
auto& viewerComponent = viewer.get<Nz::CameraComponent>();
|
||||||
|
|
||||||
Nz::Vector2f worldPos = Nz::Vector2f(viewerComponent.Unproject(Nz::Vector3f(event.x, event.y, 0.f)));
|
Nz::Vector2f worldPos = Nz::Vector2f(viewerComponent.Unproject(Nz::Vector3f(float(event.x), float(event.y), 0.f)));
|
||||||
|
|
||||||
entt::handle nearestEntity;
|
entt::handle nearestEntity;
|
||||||
if (physSytem.NearestBodyQuery(worldPos, 1.f, 0, 0xFFFFFFFF, 0xFFFFFFFF, &nearestEntity))
|
if (physSytem.NearestBodyQuery(worldPos, 1.f, 0, 0xFFFFFFFF, 0xFFFFFFFF, &nearestEntity))
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ namespace Nz
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
constexpr BoundingVolume();
|
constexpr BoundingVolume();
|
||||||
constexpr BoundingVolume(Extent Extend);
|
constexpr explicit BoundingVolume(Extent Extend);
|
||||||
constexpr BoundingVolume(const Box<T>& box);
|
constexpr explicit BoundingVolume(const Box<T>& box);
|
||||||
constexpr BoundingVolume(const OrientedBox<T>& orientedBox);
|
constexpr explicit BoundingVolume(const OrientedBox<T>& orientedBox);
|
||||||
template<typename U> constexpr explicit BoundingVolume(const BoundingVolume<U>& volume);
|
template<typename U> constexpr explicit BoundingVolume(const BoundingVolume<U>& volume);
|
||||||
constexpr BoundingVolume(const BoundingVolume&) = default;
|
constexpr BoundingVolume(const BoundingVolume&) = default;
|
||||||
constexpr BoundingVolume(BoundingVolume&&) = default;
|
constexpr BoundingVolume(BoundingVolume&&) = default;
|
||||||
|
|
|
||||||
|
|
@ -358,7 +358,7 @@ namespace Nz
|
||||||
Box<T> destBox = to.obb.localBox;
|
Box<T> destBox = to.obb.localBox;
|
||||||
destBox.Scale(interpolation);
|
destBox.Scale(interpolation);
|
||||||
|
|
||||||
return { destBox };
|
return BoundingVolume{ destBox };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -379,7 +379,7 @@ namespace Nz
|
||||||
Box<T> fromBox = from.obb.localBox;
|
Box<T> fromBox = from.obb.localBox;
|
||||||
fromBox.Scale(T(1.0) - interpolation);
|
fromBox.Scale(T(1.0) - interpolation);
|
||||||
|
|
||||||
return { fromBox };
|
return BoundingVolume{ fromBox };
|
||||||
}
|
}
|
||||||
|
|
||||||
case Extent::Infinite:
|
case Extent::Infinite:
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ namespace Nz
|
||||||
case Extent::Finite:
|
case Extent::Finite:
|
||||||
{
|
{
|
||||||
if (Intersect(volume.aabb))
|
if (Intersect(volume.aabb))
|
||||||
return Intersect(volume.obb, closestHit, furthestHit);
|
return true; // TODO: Should test OBB but there's currently no way of doing so (OrientedBox don't store enough info?)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ namespace Nz
|
||||||
virtual ~AbstractAtlas();
|
virtual ~AbstractAtlas();
|
||||||
|
|
||||||
virtual void Clear() = 0;
|
virtual void Clear() = 0;
|
||||||
virtual void Free(SparsePtr<const Rectui> rects, SparsePtr<unsigned int> layers, unsigned int count) = 0;
|
virtual void Free(SparsePtr<const Rectui> rects, SparsePtr<std::size_t> layers, std::size_t count) = 0;
|
||||||
virtual AbstractImage* GetLayer(unsigned int layerIndex) const = 0;
|
virtual AbstractImage* GetLayer(std::size_t layerIndex) const = 0;
|
||||||
virtual std::size_t GetLayerCount() const = 0;
|
virtual std::size_t GetLayerCount() const = 0;
|
||||||
virtual DataStoreFlags GetStorage() const = 0;
|
virtual DataStoreFlags GetStorage() const = 0;
|
||||||
virtual bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) = 0;
|
virtual bool Insert(const Image& image, Rectui* rect, bool* flipped, std::size_t* layerIndex) = 0;
|
||||||
|
|
||||||
AbstractAtlas& operator=(const AbstractAtlas&) = delete;
|
AbstractAtlas& operator=(const AbstractAtlas&) = delete;
|
||||||
AbstractAtlas& operator=(AbstractAtlas&&) noexcept = default;
|
AbstractAtlas& operator=(AbstractAtlas&&) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ namespace Nz
|
||||||
|
|
||||||
struct Glyph
|
struct Glyph
|
||||||
{
|
{
|
||||||
|
std::size_t layerIndex;
|
||||||
Recti aabb;
|
Recti aabb;
|
||||||
Rectui atlasRect;
|
Rectui atlasRect;
|
||||||
bool requireFauxBold;
|
bool requireFauxBold;
|
||||||
|
|
@ -105,7 +106,6 @@ namespace Nz
|
||||||
bool valid;
|
bool valid;
|
||||||
float fauxOutlineThickness;
|
float fauxOutlineThickness;
|
||||||
int advance;
|
int advance;
|
||||||
unsigned int layerIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SizeInfo
|
struct SizeInfo
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,16 @@ namespace Nz
|
||||||
|
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
void Free(SparsePtr<const Rectui> rects, SparsePtr<unsigned int> layers, unsigned int count) override;
|
void Free(SparsePtr<const Rectui> rects, SparsePtr<std::size_t> layers, std::size_t count) override;
|
||||||
|
|
||||||
unsigned int GetMaxLayerSize() const;
|
unsigned int GetMaxLayerSize() const;
|
||||||
GuillotineBinPack::FreeRectChoiceHeuristic GetRectChoiceHeuristic() const;
|
GuillotineBinPack::FreeRectChoiceHeuristic GetRectChoiceHeuristic() const;
|
||||||
GuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const;
|
GuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const;
|
||||||
AbstractImage* GetLayer(unsigned int layerIndex) const override;
|
AbstractImage* GetLayer(std::size_t layerIndex) const override;
|
||||||
std::size_t GetLayerCount() const override;
|
std::size_t GetLayerCount() const override;
|
||||||
DataStoreFlags GetStorage() const override;
|
DataStoreFlags GetStorage() const override;
|
||||||
|
|
||||||
bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) override;
|
bool Insert(const Image& image, Rectui* rect, bool* flipped, std::size_t* layerIndex) override;
|
||||||
|
|
||||||
void SetMaxLayerSize(unsigned int maxLayerSize);
|
void SetMaxLayerSize(unsigned int maxLayerSize);
|
||||||
void SetRectChoiceHeuristic(GuillotineBinPack::FreeRectChoiceHeuristic heuristic);
|
void SetRectChoiceHeuristic(GuillotineBinPack::FreeRectChoiceHeuristic heuristic);
|
||||||
|
|
|
||||||
|
|
@ -627,7 +627,7 @@ std::shared_ptr<Nz::SubMesh> ProcessSubMesh(const std::filesystem::path& originP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPath /= std::filesystem::u8path(filename);
|
targetPath /= Nz::Utf8Path(filename);
|
||||||
|
|
||||||
if (embeddedTexture->mHeight == 0)
|
if (embeddedTexture->mHeight == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -638,7 +638,7 @@ std::shared_ptr<Nz::SubMesh> ProcessSubMesh(const std::filesystem::path& originP
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPath.replace_extension(std::filesystem::u8path(embeddedTexture->achFormatHint));
|
targetPath.replace_extension(Nz::Utf8Path(embeddedTexture->achFormatHint));
|
||||||
|
|
||||||
if (!Nz::File::WriteWhole(targetPath, embeddedTexture->pcData, embeddedTexture->mWidth))
|
if (!Nz::File::WriteWhole(targetPath, embeddedTexture->pcData, embeddedTexture->mWidth))
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -697,7 +697,7 @@ std::shared_ptr<Nz::SubMesh> ProcessSubMesh(const std::filesystem::path& originP
|
||||||
matData.SetParameter(textureKey, Nz::PathToString(embeddedTexturePath));
|
matData.SetParameter(textureKey, Nz::PathToString(embeddedTexturePath));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
matData.SetParameter(textureKey, Nz::PathToString((originPath / std::filesystem::u8path(path.data, path.data + path.length))));
|
matData.SetParameter(textureKey, Nz::PathToString((originPath / Nz::Utf8Path(std::string_view(path.data, path.data + path.length)))));
|
||||||
|
|
||||||
if (wrapKey)
|
if (wrapKey)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramePipelinePass::RegisterMaterialInstance(const MaterialInstance& materialInstance)
|
void FramePipelinePass::RegisterMaterialInstance(const MaterialInstance& /*materialInstance*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramePipelinePass::UnregisterMaterialInstance(const MaterialInstance& materialInstance)
|
void FramePipelinePass::UnregisterMaterialInstance(const MaterialInstance& /*materialInstance*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ namespace Nz
|
||||||
m_commandBuffer.BlitTextureToWindow(glTexture, fromBox, Boxui(0, 0, 0, swapchainSize.x, swapchainSize.y, 1), SamplerFilter::Linear);
|
m_commandBuffer.BlitTextureToWindow(glTexture, fromBox, Boxui(0, 0, 0, swapchainSize.x, swapchainSize.y, 1), SamplerFilter::Linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLCommandBufferBuilder::BuildMipmaps(Texture& texture, UInt8 baseLevel, UInt8 levelCount, PipelineStageFlags srcStageMask, PipelineStageFlags /*dstStageMask*/, MemoryAccessFlags /*srcAccessMask*/, MemoryAccessFlags /*dstAccessMask*/, TextureLayout /*oldLayout*/, TextureLayout /*newLayout*/)
|
void OpenGLCommandBufferBuilder::BuildMipmaps(Texture& texture, UInt8 baseLevel, UInt8 levelCount, PipelineStageFlags /*srcStageMask*/, PipelineStageFlags /*dstStageMask*/, MemoryAccessFlags /*srcAccessMask*/, MemoryAccessFlags /*dstAccessMask*/, TextureLayout /*oldLayout*/, TextureLayout /*newLayout*/)
|
||||||
{
|
{
|
||||||
OpenGLTexture& glTexture = SafeCast<OpenGLTexture&>(texture);
|
OpenGLTexture& glTexture = SafeCast<OpenGLTexture&>(texture);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -506,8 +506,8 @@ namespace Nz
|
||||||
if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0)
|
if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0)
|
||||||
{
|
{
|
||||||
// Add a small border to prevent GPU to sample another glyph pixel
|
// Add a small border to prevent GPU to sample another glyph pixel
|
||||||
glyph.atlasRect.width += m_glyphBorder*2;
|
glyph.atlasRect.width += m_glyphBorder * 2;
|
||||||
glyph.atlasRect.height += m_glyphBorder*2;
|
glyph.atlasRect.height += m_glyphBorder * 2;
|
||||||
|
|
||||||
if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex))
|
if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex))
|
||||||
{
|
{
|
||||||
|
|
@ -518,8 +518,8 @@ namespace Nz
|
||||||
// Recenter and remove glyph border
|
// Recenter and remove glyph border
|
||||||
glyph.atlasRect.x += m_glyphBorder;
|
glyph.atlasRect.x += m_glyphBorder;
|
||||||
glyph.atlasRect.y += m_glyphBorder;
|
glyph.atlasRect.y += m_glyphBorder;
|
||||||
glyph.atlasRect.width -= m_glyphBorder*2;
|
glyph.atlasRect.width -= m_glyphBorder * 2;
|
||||||
glyph.atlasRect.height -= m_glyphBorder*2;
|
glyph.atlasRect.height -= m_glyphBorder * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
glyph.aabb = fontGlyph.aabb;
|
glyph.aabb = fontGlyph.aabb;
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,11 @@ namespace Nz
|
||||||
OnAtlasCleared(this);
|
OnAtlasCleared(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuillotineImageAtlas::Free(SparsePtr<const Rectui> rects, SparsePtr<unsigned int> layers, unsigned int count)
|
void GuillotineImageAtlas::Free(SparsePtr<const Rectui> rects, SparsePtr<std::size_t> layers, std::size_t count)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (std::size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
NazaraAssertFmt(layers[i] < m_layers.size(), "Rectangle #{0} belongs to an out-of-bounds layer ({1} >= {2})", i, layers[i], m_layers.size());
|
||||||
if (layers[i] >= m_layers.size())
|
|
||||||
{
|
|
||||||
NazaraWarning("Rectangle #" + NumberToString(i) + " belong to an out-of-bounds layer (" + NumberToString(i) + " >= " + NumberToString(m_layers.size()) + ")");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_layers[layers[i]].binPack.FreeRectangle(rects[i]);
|
m_layers[layers[i]].binPack.FreeRectangle(rects[i]);
|
||||||
m_layers[layers[i]].freedRectangles++;
|
m_layers[layers[i]].freedRectangles++;
|
||||||
|
|
@ -58,15 +52,9 @@ namespace Nz
|
||||||
return m_rectSplitHeuristic;
|
return m_rectSplitHeuristic;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractImage* GuillotineImageAtlas::GetLayer(unsigned int layerIndex) const
|
AbstractImage* GuillotineImageAtlas::GetLayer(std::size_t layerIndex) const
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraAssertFmt(layerIndex < m_layers.size(), "layer index out of range ({0} >= {1})", layerIndex, m_layers.size());
|
||||||
if (layerIndex >= m_layers.size())
|
|
||||||
{
|
|
||||||
NazaraErrorFmt("layer index out of range ({0} >= {1})", layerIndex, m_layers.size());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Layer& layer = m_layers[layerIndex];
|
Layer& layer = m_layers[layerIndex];
|
||||||
ProcessGlyphQueue(layer);
|
ProcessGlyphQueue(layer);
|
||||||
|
|
@ -84,75 +72,74 @@ namespace Nz
|
||||||
return DataStorage::Software;
|
return DataStorage::Software;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuillotineImageAtlas::Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex)
|
bool GuillotineImageAtlas::Insert(const Image& image, Rectui* rect, bool* flipped, std::size_t* layerIndex)
|
||||||
{
|
{
|
||||||
|
// Ensure there's at least one layer before inserting
|
||||||
if (m_layers.empty())
|
if (m_layers.empty())
|
||||||
// On créé une première couche s'il n'y en a pas
|
m_layers.emplace_back();
|
||||||
m_layers.resize(1);
|
|
||||||
|
|
||||||
// Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après
|
// Reserve some space for that rectangle (pixel copy only happens in ProcessGlyphQueue)
|
||||||
for (unsigned int i = 0; i < m_layers.size(); ++i)
|
for (std::size_t i = 0; i < m_layers.size(); ++i)
|
||||||
{
|
{
|
||||||
Layer& layer = m_layers[i];
|
Layer& layer = m_layers[i];
|
||||||
|
|
||||||
// Une fois qu'un certain nombre de rectangles ont étés libérés d'une couche, on fusionne les rectangles libres
|
// Try to reduce fragmentation by merging free rectangles if at least X rectangles were freed before inserting
|
||||||
if (layer.freedRectangles > 10) // Valeur totalement arbitraire
|
if (layer.freedRectangles > 10)
|
||||||
{
|
{
|
||||||
while (layer.binPack.MergeFreeRectangles()); // Tant qu'une fusion est possible
|
while (layer.binPack.MergeFreeRectangles());
|
||||||
layer.freedRectangles = 0; // Et on repart de zéro
|
layer.freedRectangles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic))
|
if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic))
|
||||||
{
|
{
|
||||||
// Insertion réussie dans l'une des couches, on place le glyphe en file d'attente
|
// Found some space, queue glyph copy
|
||||||
layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1);
|
layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1);
|
||||||
QueuedGlyph& glyph = layer.queuedGlyphs.back();
|
QueuedGlyph& glyph = layer.queuedGlyphs.back();
|
||||||
glyph.flipped = *flipped;
|
glyph.flipped = *flipped;
|
||||||
glyph.image = image; // Merci le Copy-On-Write
|
glyph.image = image; // Copy-On-Write
|
||||||
glyph.rect = *rect;
|
glyph.rect = *rect;
|
||||||
|
|
||||||
*layerIndex = i;
|
*layerIndex = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (i == m_layers.size() - 1) // Dernière itération ?
|
else if (i == m_layers.size() - 1)
|
||||||
{
|
{
|
||||||
// Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ?
|
// Last layer and glyph can't be inserted, try to double the layer size
|
||||||
Vector2ui newSize = layer.binPack.GetSize()*2;
|
Vector2ui newSize = layer.binPack.GetSize() * 2;
|
||||||
if (newSize == Vector2ui::Zero())
|
if (newSize == Vector2ui::Zero())
|
||||||
newSize = s_guillotineAtlasStartSize;
|
newSize = s_guillotineAtlasStartSize;
|
||||||
|
|
||||||
// Limit image atlas size to prevent allocating too much contiguous memory blocks
|
// Limit image atlas size to prevent allocating too much contiguous memory blocks
|
||||||
if (newSize.x <= m_maxLayerSize && newSize.y <= m_maxLayerSize && ResizeLayer(layer, newSize))
|
if (newSize.x <= m_maxLayerSize && newSize.y <= m_maxLayerSize && ResizeLayer(layer, newSize))
|
||||||
{
|
{
|
||||||
// Yes we can!
|
// Atlas has been enlarged successfully, re-run iteration
|
||||||
layer.binPack.Expand(newSize); // On ajuste l'atlas virtuel
|
layer.binPack.Expand(newSize);
|
||||||
|
|
||||||
// Et on relance la boucle sur la nouvelle dernière couche
|
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle
|
// Atlas cannot be enlarged, make a new layer
|
||||||
newSize = s_guillotineAtlasStartSize;
|
newSize = s_guillotineAtlasStartSize;
|
||||||
|
|
||||||
Layer newLayer;
|
Layer newLayer;
|
||||||
if (!ResizeLayer(newLayer, newSize))
|
if (!ResizeLayer(newLayer, newSize))
|
||||||
{
|
{
|
||||||
// Impossible d'allouer une nouvelle couche, nous manquons probablement de mémoire (ou le glyphe est trop grand)
|
|
||||||
NazaraError("failed to allocate new layer, we are probably out of memory");
|
NazaraError("failed to allocate new layer, we are probably out of memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
newLayer.binPack.Reset(newSize);
|
newLayer.binPack.Reset(newSize);
|
||||||
|
|
||||||
m_layers.emplace_back(std::move(newLayer)); // Insertion du layer
|
m_layers.emplace_back(std::move(newLayer));
|
||||||
|
|
||||||
// On laisse la boucle insérer toute seule le rectangle à la prochaine itération
|
// This new layer will be processed on next iteration
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NazaraInternalError("Unknown error"); // Normalement on ne peut pas arriver ici
|
// It shouldn't be possible to get here (TODO: Add NAZARA_UNREACHEABLE)
|
||||||
|
NazaraInternalError("unknown error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,18 +171,15 @@ namespace Nz
|
||||||
{
|
{
|
||||||
std::shared_ptr<AbstractImage> newImage = ResizeImage(layer.image, size);
|
std::shared_ptr<AbstractImage> newImage = ResizeImage(layer.image, size);
|
||||||
if (!newImage)
|
if (!newImage)
|
||||||
return false; // Nous n'avons pas pu allouer
|
return false; // Allocation failed
|
||||||
|
|
||||||
if (newImage == layer.image) // Le layer a été agrandi dans le même objet, pas de souci
|
if (newImage == layer.image)
|
||||||
return true;
|
return true; // The image object hasn't changed
|
||||||
|
|
||||||
// On indique à ceux que ça intéresse qu'on a changé de pointeur
|
// Image object did change, notify and store the new one
|
||||||
// (chose très importante pour ceux qui le stockent)
|
|
||||||
OnAtlasLayerChange(this, layer.image.get(), newImage.get());
|
OnAtlasLayerChange(this, layer.image.get(), newImage.get());
|
||||||
|
|
||||||
// Et on ne met à jour le pointeur qu'après (car cette ligne libère également l'ancienne image)
|
|
||||||
layer.image = std::move(newImage);
|
layer.image = std::move(newImage);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,41 +192,41 @@ namespace Nz
|
||||||
unsigned int glyphWidth = glyph.image.GetWidth();
|
unsigned int glyphWidth = glyph.image.GetWidth();
|
||||||
unsigned int glyphHeight = glyph.image.GetHeight();
|
unsigned int glyphHeight = glyph.image.GetHeight();
|
||||||
|
|
||||||
// Calcul de l'éventuel padding (pixels de contour)
|
// Compute padding
|
||||||
unsigned int paddingX;
|
unsigned int paddingX;
|
||||||
unsigned int paddingY;
|
unsigned int paddingY;
|
||||||
if (glyph.flipped)
|
if (glyph.flipped)
|
||||||
{
|
{
|
||||||
paddingX = (glyph.rect.height - glyphWidth)/2;
|
paddingX = (glyph.rect.height - glyphWidth) / 2;
|
||||||
paddingY = (glyph.rect.width - glyphHeight)/2;
|
paddingY = (glyph.rect.width - glyphHeight) / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
paddingX = (glyph.rect.width - glyphWidth)/2;
|
paddingX = (glyph.rect.width - glyphWidth) / 2;
|
||||||
paddingY = (glyph.rect.height - glyphHeight)/2;
|
paddingY = (glyph.rect.height - glyphHeight) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paddingX > 0 || paddingY > 0)
|
if (paddingX > 0 || paddingY > 0)
|
||||||
{
|
{
|
||||||
// On remplit les contours
|
// Prefill the rectangle if we have some padding
|
||||||
pixelBuffer.resize(glyph.rect.width * glyph.rect.height);
|
pixelBuffer.resize(glyph.rect.width * glyph.rect.height);
|
||||||
std::memset(pixelBuffer.data(), 0, glyph.rect.width*glyph.rect.height*sizeof(UInt8));
|
std::memset(pixelBuffer.data(), 0, glyph.rect.width * glyph.rect.height * sizeof(UInt8));
|
||||||
|
|
||||||
layer.image->Update(pixelBuffer.data(), glyph.rect);
|
layer.image->Update(pixelBuffer.data(), glyph.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt8* pixels;
|
const UInt8* pixels;
|
||||||
// On copie le glyphe dans l'atlas
|
// Copy the glyph to the atlas
|
||||||
if (glyph.flipped)
|
if (glyph.flipped)
|
||||||
{
|
{
|
||||||
pixelBuffer.resize(glyphHeight * glyphWidth);
|
pixelBuffer.resize(glyphHeight * glyphWidth);
|
||||||
|
|
||||||
// On tourne le glyphe pour qu'il rentre dans le rectangle
|
// Rotate the glyph
|
||||||
const UInt8* src = glyph.image.GetConstPixels();
|
const UInt8* src = glyph.image.GetConstPixels();
|
||||||
UInt8* ptr = pixelBuffer.data();
|
UInt8* ptr = pixelBuffer.data();
|
||||||
|
|
||||||
unsigned int lineStride = glyphWidth*sizeof(UInt8); // BPP = 1
|
unsigned int lineStride = glyphWidth * sizeof(UInt8); // BPP = 1
|
||||||
src += lineStride-1; // Départ en haut à droite
|
src += lineStride-1; // Top-right
|
||||||
for (unsigned int x = 0; x < glyphWidth; ++x)
|
for (unsigned int x = 0; x < glyphWidth; ++x)
|
||||||
{
|
{
|
||||||
for (unsigned int y = 0; y < glyphHeight; ++y)
|
for (unsigned int y = 0; y < glyphHeight; ++y)
|
||||||
|
|
@ -261,7 +245,7 @@ namespace Nz
|
||||||
pixels = glyph.image.GetConstPixels();
|
pixels = glyph.image.GetConstPixels();
|
||||||
|
|
||||||
layer.image->Update(pixels, Rectui(glyph.rect.x + paddingX, glyph.rect.y + paddingY, glyphWidth, glyphHeight), 0, glyphWidth, glyphHeight);
|
layer.image->Update(pixels, Rectui(glyph.rect.x + paddingX, glyph.rect.y + paddingY, glyphWidth, glyphHeight), 0, glyphWidth, glyphHeight);
|
||||||
glyph.image.Destroy(); // On libère l'image dès que possible (pour réduire la consommation)
|
glyph.image.Destroy(); // Free the image as soon as possible (to reduce memory usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.queuedGlyphs.clear();
|
layer.queuedGlyphs.clear();
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ int main()
|
||||||
std::size_t bufferSize = bufferLayout.GetAlignedSize();
|
std::size_t bufferSize = bufferLayout.GetAlignedSize();
|
||||||
|
|
||||||
std::vector<Nz::UInt8> particleBufferInitialData(bufferSize);
|
std::vector<Nz::UInt8> particleBufferInitialData(bufferSize);
|
||||||
Nz::AccessByOffset<Nz::UInt32&>(particleBufferInitialData.data(), particleCountOffset) = particleCount;
|
Nz::AccessByOffset<Nz::UInt32&>(particleBufferInitialData.data(), particleCountOffset) = Nz::SafeCast<Nz::UInt32>(particleCount);
|
||||||
|
|
||||||
Nz::Vector2f logoImageSize(Nz::Vector2ui(logo->GetSize()));
|
Nz::Vector2f logoImageSize(Nz::Vector2ui(logo->GetSize()));
|
||||||
float logoRatio = logoImageSize.x / logoImageSize.y;
|
float logoRatio = logoImageSize.x / logoImageSize.y;
|
||||||
|
|
@ -213,7 +213,7 @@ int main()
|
||||||
std::size_t viewerBufferSize = viewerLayout.GetAlignedSize();
|
std::size_t viewerBufferSize = viewerLayout.GetAlignedSize();
|
||||||
|
|
||||||
std::vector<Nz::UInt8> viewerBufferInitialData(viewerBufferSize);
|
std::vector<Nz::UInt8> viewerBufferInitialData(viewerBufferSize);
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(viewerBufferInitialData.data(), projectionMatrixOffset) = Nz::Matrix4f::Ortho(0.f, windowSize.x, 0.f, windowSize.y);
|
Nz::AccessByOffset<Nz::Matrix4f&>(viewerBufferInitialData.data(), projectionMatrixOffset) = Nz::Matrix4f::Ortho(0.f, float(windowSize.x), 0.f, float(windowSize.y));
|
||||||
|
|
||||||
std::shared_ptr<Nz::RenderBuffer> uniformBuffer = device->InstantiateBuffer(Nz::BufferType::Uniform, viewerBufferSize, Nz::BufferUsage::DeviceLocal, viewerBufferInitialData.data());
|
std::shared_ptr<Nz::RenderBuffer> uniformBuffer = device->InstantiateBuffer(Nz::BufferType::Uniform, viewerBufferSize, Nz::BufferUsage::DeviceLocal, viewerBufferInitialData.data());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue