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; }
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; }
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; }
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; }