Beispiel #1
0
// For this generic implementation, we just call GetPixels and copy that data
// to the buffer. Texture formats that can do better than paletted images
// should provide their own implementation that may preserve the original
// color data. Note that the buffer expects row-major data, since that's
// generally more convenient for any non-Doom image formats, and it doesn't
// need to be used by any of Doom's column drawing routines.
void FTexture::FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt)
{
	const BYTE *pix;
	int x, y, w, h, stride;

	w = GetWidth();
	h = GetHeight();

	switch (fmt)
	{
	case TEX_Pal:
	case TEX_Gray:
		pix = GetPixels();
		stride = pitch - w;
		for (y = 0; y < h; ++y)
		{
			const BYTE *pix2 = pix;
			for (x = 0; x < w; ++x)
			{
				*buff++ = *pix2;
				pix2 += h;
			}
			pix++;
			buff += stride;
		}
		break;

	case TEX_RGB:
	{
		FCopyInfo inf = {OP_OVERWRITE, BLEND_NONE, {0}, 0, 0};
		FBitmap bmp(buff, pitch, pitch/4, height);
		CopyTrueColorPixels(&bmp, 0, 0, 0, &inf); 
		break;
	}

	default:
		I_Error("FTexture::FillBuffer: Unsupported format %d", fmt);
	}
}
Beispiel #2
0
int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
{
	int retv = -1;

	if (bRedirect)
	{ // Redirect straight to the real texture's routine.
		return Parts[0].Texture->CopyTrueColorPixels(bmp, x, y, rotate, inf);
	}

	if (rotate != 0 || (inf != NULL && ((inf->op != OP_OVERWRITE && inf->op != OP_COPY) || inf->blend != BLEND_NONE)))
	{ // We are doing some sort of fancy stuff to the destination bitmap, so composite to
	  // a temporary bitmap, and copy that.
		FBitmap tbmp;
		if (tbmp.Create(Width, Height))
		{
			retv = MAX(retv, CopyTrueColorPixels(&tbmp, 0, 0, 0));
			bmp->CopyPixelDataRGB(x, y, tbmp.GetPixels(), Width, Height,
				4, tbmp.GetPitch(), rotate, CF_BGRA, inf);
		}
		return retv;
	}

	// When compositing a multipatch texture with multipatch parts,
	// drawing must be restricted to the actual area which is covered by this texture.
	FClipRect saved_cr = bmp->GetClipRect();
	bmp->IntersectClipRect(x, y, Width, Height);

	if (inf != NULL && inf->op == OP_OVERWRITE)
	{
		bmp->Zero();
	}

	for(int i = 0; i < NumParts; i++)
	{
		int ret = -1;
		FCopyInfo info;

		if (Parts[i].Texture->bHasCanvas) continue;	// cannot use camera textures as patch.

		memset (&info, 0, sizeof(info));
		info.alpha = Parts[i].Alpha;
		info.invalpha = BLENDUNIT - info.alpha;
		info.op = ECopyOp(Parts[i].op);
		PalEntry b = Parts[i].Blend;
		if (b.a == 0 && b != BLEND_NONE)
		{
			info.blend = EBlend(b.d);
		}
		else if (b.a != 0)
		{
			if (b.a == 255)
			{
				info.blendcolor[0] = b.r * BLENDUNIT / 255;
				info.blendcolor[1] = b.g * BLENDUNIT / 255;
				info.blendcolor[2] = b.b * BLENDUNIT / 255;
				info.blend = BLEND_MODULATE;
			}
			else
			{
				blend_t blendalpha = b.a * BLENDUNIT / 255;
				info.blendcolor[0] = b.r * blendalpha;
				info.blendcolor[1] = b.g * blendalpha;
				info.blendcolor[2] = b.b * blendalpha;
				info.blendcolor[3] = FRACUNIT - blendalpha;
				info.blend = BLEND_OVERLAY;
			}
		}

		if (Parts[i].Translation != NULL)
		{ // Using a translation forces downconversion to the base palette
			ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation->Palette, &info);
		}
		else
		{
			ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info);
		}
		// treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done.
		if (ret == -1) retv = ret;
		else if (retv != -1 && ret > retv) retv = ret;
	}
	// Restore previous clipping rectangle.
	bmp->SetClipRect(saved_cr);
	return retv;
}