AbstractImage* GuillotineTextureAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const { std::unique_ptr<Texture> newTexture(new Texture); if (newTexture->Create(ImageType_2D, PixelFormatType_A8, size.x, size.y, 1)) { if (oldImage) { Texture* oldTexture = static_cast<Texture*>(oldImage); // Copie des anciennes données ///TODO: Copie de texture à texture Image image; if (!oldTexture->Download(&image)) { NazaraError("Failed to download old texture"); return nullptr; } if (!newTexture->Update(image, Rectui(0, 0, image.GetWidth(), image.GetHeight()))) { NazaraError("Failed to update texture"); return nullptr; } } return newTexture.release(); } else { // Si on arrive ici c'est que la taille demandée est trop grande pour la carte graphique // ou que nous manquons de mémoire return nullptr; } }
AbstractImage* GuillotineImageAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const { std::unique_ptr<Image> newImage(new Image(ImageType_2D, PixelFormatType_A8, size.x, size.y)); if (oldImage) { Image& image = *static_cast<Image*>(oldImage); newImage->Copy(image, Rectui(size), Vector2ui(0, 0)); // Copie des anciennes données } return newImage.release(); }
bool RenderWindow::CopyToImage(AbstractImage* image, const Vector3ui& dstPos) const { #if NAZARA_RENDERER_SAFE if (!m_context) { NazaraError("Window has not been created"); return false; } #endif return CopyToImage(image, Rectui(Vector2ui(0U), GetSize()), dstPos); }
void GuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const { std::vector<UInt8> pixelBuffer; for (QueuedGlyph& glyph : layer.queuedGlyphs) { unsigned int glyphWidth = glyph.image.GetWidth(); unsigned int glyphHeight = glyph.image.GetHeight(); // Calcul de l'éventuel padding (pixels de contour) unsigned int paddingX; unsigned int paddingY; if (glyph.flipped) { paddingX = (glyph.rect.height - glyphWidth)/2; paddingY = (glyph.rect.width - glyphHeight)/2; } else { paddingX = (glyph.rect.width - glyphWidth)/2; paddingY = (glyph.rect.height - glyphHeight)/2; } if (paddingX > 0 || paddingY > 0) { // On remplit les contours pixelBuffer.resize(glyph.rect.width * glyph.rect.height); std::memset(pixelBuffer.data(), 0, glyph.rect.width*glyph.rect.height*sizeof(UInt8)); layer.image->Update(pixelBuffer.data(), glyph.rect); } const UInt8* pixels; // On copie le glyphe dans l'atlas if (glyph.flipped) { pixelBuffer.resize(glyphHeight * glyphWidth); // On tourne le glyphe pour qu'il rentre dans le rectangle const UInt8* src = glyph.image.GetConstPixels(); UInt8* ptr = pixelBuffer.data(); unsigned int lineStride = glyphWidth*sizeof(UInt8); // BPP = 1 src += lineStride-1; // Départ en haut à droite for (unsigned int x = 0; x < glyphWidth; ++x) { for (unsigned int y = 0; y < glyphHeight; ++y) { *ptr++ = *src; src += lineStride; } src -= glyphHeight*lineStride + 1; } pixels = pixelBuffer.data(); std::swap(glyphWidth, glyphHeight); } else pixels = glyph.image.GetConstPixels(); 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) } layer.queuedGlyphs.clear(); }