Beispiel #1
0
void FMultiPatchTexture::MakeTexture ()
{
	// Add a little extra space at the end if the texture's height is not
	// a power of 2, in case somebody accidentally makes it repeat vertically.
	int numpix = Width * Height + (1 << HeightBits) - Height;
	BYTE blendwork[256];
	bool hasTranslucent = false;

	Pixels = new BYTE[numpix];
	memset (Pixels, 0, numpix);

	for (int i = 0; i < NumParts; ++i)
	{
		if (Parts[i].op != OP_COPY)
		{
			hasTranslucent = true;
		}
	}

	if (!hasTranslucent)
	{
		for (int i = 0; i < NumParts; ++i)
		{
			if (Parts[i].Texture->bHasCanvas) continue;	// cannot use camera textures as patch.
		
			BYTE *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL;
			{
				if (Parts[i].Blend != 0)
				{
					trans = GetBlendMap(Parts[i].Blend, blendwork);
				}
				Parts[i].Texture->CopyToBlock (Pixels, Width, Height,
					Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans);
			}
		}
	}
	else
	{
		// In case there are translucent patches let's do the composition in
		// True color to keep as much precision as possible before downconverting to the palette.
		BYTE *buffer = new BYTE[Width * Height * 4];
		memset(buffer, 0, Width * Height * 4);
		FillBuffer(buffer, Width * 4, Height, TEX_RGB);
		for(int y = 0; y < Height; y++)
		{
			BYTE *in = buffer + Width * y * 4;
			BYTE *out = Pixels + y;
			for (int x = 0; x < Width; x++)
			{
				if (*out == 0 && in[3] != 0)
				{
					*out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3];
				}
				out += Height;
				in += 4;
			}
		}
		delete [] buffer;
	}
Beispiel #2
0
void FMultiPatchTexture::MakeTexture ()
{
	// Add a little extra space at the end if the texture's height is not
	// a power of 2, in case somebody accidentally makes it repeat vertically.
	int numpix = Width * Height + (1 << HeightBits) - Height;
	BYTE blendwork[256];
	bool hasTranslucent = false;

	Pixels = new BYTE[numpix];
	memset (Pixels, 0, numpix);

	// This is not going to be easy for paletted output. Using the
	// real time mixing tables gives results that just look bad and
	// downconverting a true color image also has its problems so the only
	// real choice is to do normal compositing with any translucent patch
	// just masking the affected pixels, then do a full true color composition
	// and merge these pixels in.
	for (int i = 0; i < NumParts; ++i)
	{
		BYTE *trans = Parts[i].Translation ? Parts[i].Translation->Remap : NULL;
		if (Parts[i].op != OP_COPY)
		{
			hasTranslucent = true;
		}
		else
		{
			if (Parts[i].Blend != 0)
			{
				trans = GetBlendMap(Parts[i].Blend, blendwork);
			}
			Parts[i].Texture->CopyToBlock (Pixels, Width, Height,
				Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans);
		}
	}

	if (hasTranslucent)
	{
		// In case there are translucent patches let's do the composition in
		// True color to keep as much precision as possible before downconverting to the palette.
		BYTE *buffer = new BYTE[Width * Height * 4];
		memset(buffer, 0, Width * Height * 4);
		FillBuffer(buffer, Width * 4, Height, TEX_RGB);
		for(int y = 0; y < Height; y++)
		{
			BYTE *in = buffer + Width * y * 4;
			BYTE *out = Pixels + y;
			for (int x = 0; x < Width; x++)
			{
				if (*out == 0 && in[3] != 0)
				{
					*out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3];
				}
				out += Height;
				in += 4;
			}
		}
		delete [] buffer;
	}
Beispiel #3
0
uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style)
{
	// Add a little extra space at the end if the texture's height is not
	// a power of 2, in case somebody accidentally makes it repeat vertically.
	int numpix = Width * Height + (1 << HeightBits) - Height;
	uint8_t blendwork[256];
	bool buildrgb = bComplex;

	auto Pixels = new uint8_t[numpix];
	memset (Pixels, 0, numpix);

	if (style.Flags & STYLEF_RedIsAlpha)
	{
		buildrgb = !UseBasePalette();
	}
	else
	{
		// For regular textures we can use paletted compositing if all patches are just being copied because they all can create a paletted buffer.
		if (!buildrgb) for (int i = 0; i < NumParts; ++i)
		{
			if (Parts[i].op != OP_COPY)
			{
				buildrgb = true;
			}
		}
	}

	if (!buildrgb)
	{	
		for (int i = 0; i < NumParts; ++i)
		{
			if (Parts[i].Texture->bHasCanvas) continue;	// cannot use camera textures as patch.
		
			uint8_t *trans = Parts[i].Translation? Parts[i].Translation->Remap : nullptr;
			{
				if (Parts[i].Blend != 0)
				{
					trans = GetBlendMap(Parts[i].Blend, blendwork);
				}
				Parts[i].Texture->CopyToBlock (Pixels, Width, Height, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, style);
			}
		}
	}
	else
	{
		// In case there are translucent patches let's do the composition in
		// True color to keep as much precision as possible before downconverting to the palette.
		uint8_t *buffer = new uint8_t[Width * Height * 4];
		memset(buffer, 0, Width * Height * 4);
		FillBuffer(buffer, Width * 4, Height, TEX_RGB);
		for(int y = 0; y < Height; y++)
		{
			uint8_t *in = buffer + Width * y * 4;
			uint8_t *out = Pixels + y;
			for (int x = 0; x < Width; x++)
			{
				if (*out == 0 && in[3] != 0)
				{
					*out = RGBToPalette(style, in[2], in[1], in[0]);
				}
				out += Height;
				in += 4;
			}
		}
		delete [] buffer;
	}
	return Pixels;
}
Beispiel #4
0
TArray<uint8_t> FMultiPatchTexture::CreatePalettedPixels(int conversion)
{
	int numpix = Width * Height;
	uint8_t blendwork[256];
	bool buildrgb = bComplex;

	TArray<uint8_t> Pixels(numpix, true);
	memset (Pixels.Data(), 0, numpix);

	if (conversion == luminance)
	{
		// For alpha textures, downconversion to the palette would lose too much precision if not all patches use the palette.
		buildrgb = !UseGamePalette();
	}
	else
	{
		// For regular textures we can use paletted compositing if all patches are just being copied because they all can create a paletted buffer.
		if (!buildrgb) for (int i = 0; i < NumParts; ++i)
		{
			if (Parts[i].op != OP_COPY)
			{
				buildrgb = true;
			}
		}
	}
	if (conversion == noremap0)
	{
		// sky remapping will only happen if
		// - the texture was defined through a TEXTUREx lump (this implies only trivial copies)
		// - all patches use the base palette.
		// All other cases would not be able to properly deal with this special case.
		// For textual definitions this hack isn't necessary.
		if (bTextual || !UseGamePalette()) conversion = normal;
	}

	if (!buildrgb)
	{	
		for (int i = 0; i < NumParts; ++i)
		{
			uint8_t *trans = Parts[i].Translation? Parts[i].Translation->Remap : nullptr;
			{
				if (Parts[i].Blend != 0)
				{
					trans = GetBlendMap(Parts[i].Blend, blendwork);
				}
				CopyToBlock (Pixels.Data(), Width, Height, Parts[i].Image, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, conversion);
			}
		}
	}
	else
	{
		// In case there are translucent patches let's do the composition in
		// True color to keep as much precision as possible before downconverting to the palette.
		FBitmap PixelsIn;
		PixelsIn.Create(Width, Height);
		CopyPixels(&PixelsIn, normal);
		for(int y = 0; y < Height; y++)
		{
			uint8_t *in = PixelsIn.GetPixels() + Width * y * 4;
			uint8_t *out = Pixels.Data() + y;
			for (int x = 0; x < Width; x++)
			{
				if (*out == 0 && in[3] != 0)
				{
					*out = ImageHelpers::RGBToPalette(conversion == luminance, in[2], in[1], in[0]);
				}
				out += Height;
				in += 4;
			}
		}
	}
	return Pixels;
}