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;
		}
	}
Пример #2
0
	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();
	}
Пример #3
0
	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);
	}
Пример #4
0
	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();
	}