diff --git a/src/g_strife/strife_sbar.cpp b/src/g_strife/strife_sbar.cpp index e1fcb3cda1..eb3fa26087 100644 --- a/src/g_strife/strife_sbar.cpp +++ b/src/g_strife/strife_sbar.cpp @@ -34,7 +34,6 @@ public: const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); - const uint32_t *GetPixelsBgra() override; bool CheckModified (); void SetVial (int level); @@ -116,16 +115,6 @@ const BYTE *FHealthBar::GetPixels () return Pixels; } -const uint32_t *FHealthBar::GetPixelsBgra() -{ - if (NeedRefresh) - { - MakeTexture(); - PixelsBgra.clear(); - } - return FTexture::GetPixelsBgra(); -} - void FHealthBar::SetVial (int level) { if (level < 0) diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index 7b7e9ca5d4..16671975a0 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -78,7 +78,6 @@ public: const BYTE *GetColumn(unsigned int column, const Span **spans_out); const BYTE *GetPixels(); - const uint32_t *GetPixelsBgra() override; bool CheckModified(); protected: @@ -247,16 +246,6 @@ const BYTE *FBackdropTexture::GetPixels() return Pixels; } -const uint32_t *FBackdropTexture::GetPixelsBgra() -{ - if (LastRenderTic != gametic) - { - Render(); - PixelsBgra.clear(); - } - return FTexture::GetPixelsBgra(); -} - //============================================================================= // // This is one plasma and two rotozoomers. I think it turned out quite awesome. diff --git a/src/textures/jpegtexture.cpp b/src/textures/jpegtexture.cpp index f44b34d088..fc629b37e4 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/jpegtexture.cpp @@ -187,7 +187,6 @@ public: const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); - const uint32_t *GetPixelsBgra (); void Unload (); FTextureFormat GetFormat (); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); @@ -199,7 +198,6 @@ protected: Span DummySpans[2]; void MakeTexture (); - void MakeTextureBgra (); friend class FTexture; }; @@ -358,15 +356,6 @@ const BYTE *FJPEGTexture::GetPixels () return Pixels; } -const uint32_t *FJPEGTexture::GetPixelsBgra() -{ - if (PixelsBgra.empty()) - { - MakeTextureBgra(); - } - return PixelsBgra.data(); -} - //========================================================================== // // @@ -466,104 +455,6 @@ void FJPEGTexture::MakeTexture () } } -void FJPEGTexture::MakeTextureBgra() -{ - FWadLump lump = Wads.OpenLumpNum(SourceLump); - JSAMPLE *buff = NULL; - - jpeg_decompress_struct cinfo; - jpeg_error_mgr jerr; - - CreatePixelsBgraWithMipmaps(); - - cinfo.err = jpeg_std_error(&jerr); - cinfo.err->output_message = JPEG_OutputMessage; - cinfo.err->error_exit = JPEG_ErrorExit; - jpeg_create_decompress(&cinfo); - try - { - FLumpSourceMgr sourcemgr(&lump, &cinfo); - jpeg_read_header(&cinfo, TRUE); - if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) - { - Printf(TEXTCOLOR_ORANGE "Unsupported color format\n"); - throw - 1; - } - - jpeg_start_decompress(&cinfo); - - int y = 0; - buff = new BYTE[cinfo.output_width * cinfo.output_components]; - - while (cinfo.output_scanline < cinfo.output_height) - { - int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1); - BYTE *in = buff; - uint32_t *out = PixelsBgra.data() + y; - switch (cinfo.out_color_space) - { - case JCS_RGB: - for (int x = Width; x > 0; --x) - { - uint32_t r = in[0]; - uint32_t g = in[1]; - uint32_t b = in[2]; - *out = 0xff000000 | (r << 16) | (g << 8) | b; - out += Height; - in += 3; - } - break; - - case JCS_GRAYSCALE: - for (int x = Width; x > 0; --x) - { - uint32_t gray = in[0]; - *out = 0xff000000 | (gray << 16) | (gray << 8) | gray; - out += Height; - in += 1; - } - break; - - case JCS_CMYK: - // What are you doing using a CMYK image? :) - for (int x = Width; x > 0; --x) - { - // To be precise, these calculations should use 255, but - // 256 is much faster and virtually indistinguishable. - uint32_t r = in[3] - (((256 - in[0])*in[3]) >> 8); - uint32_t g = in[3] - (((256 - in[1])*in[3]) >> 8); - uint32_t b = in[3] - (((256 - in[2])*in[3]) >> 8); - *out = 0xff000000 | (r << 16) | (g << 8) | b; - out += Height; - in += 4; - } - break; - - default: - // The other colorspaces were considered above and discarded, - // but GCC will complain without a default for them here. - break; - } - y++; - } - jpeg_finish_decompress(&cinfo); - jpeg_destroy_decompress(&cinfo); - } - catch (int) - { - Printf(TEXTCOLOR_ORANGE " in texture %s\n", Name.GetChars()); - jpeg_destroy_decompress(&cinfo); - } - if (buff != NULL) - { - delete[] buff; - } - - GenerateBgraMipmaps(); -} - //=========================================================================== // diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index ee4eabe900..31d76f5674 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -57,7 +57,6 @@ public: const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); - const uint32_t *GetPixelsBgra (); void Unload (); FTextureFormat GetFormat (); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); @@ -81,7 +80,6 @@ protected: DWORD StartOfIDAT; void MakeTexture (); - void MakeTextureBgra (); friend class FTexture; }; @@ -454,15 +452,6 @@ const BYTE *FPNGTexture::GetPixels () return Pixels; } -const uint32_t *FPNGTexture::GetPixelsBgra() -{ - if (PixelsBgra.empty()) - { - MakeTextureBgra(); - } - return PixelsBgra.data(); -} - //========================================================================== // @@ -620,146 +609,6 @@ void FPNGTexture::MakeTexture () delete lump; } -void FPNGTexture::MakeTextureBgra () -{ - FileReader *lump; - - if (SourceLump >= 0) - { - lump = new FWadLump(Wads.OpenLumpNum(SourceLump)); - } - else - { - lump = new FileReader(SourceFile.GetChars()); - } - - CreatePixelsBgraWithMipmaps(); - if (StartOfIDAT != 0) - { - DWORD len, id; - lump->Seek (StartOfIDAT, SEEK_SET); - lump->Read(&len, 4); - lump->Read(&id, 4); - - if (ColorType == 0 || ColorType == 3) /* Grayscale and paletted */ - { - std::vector src(Width*Height); - M_ReadIDAT (lump, src.data(), Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); - - if (!PngPalette.empty()) - { - for (int x = 0; x < Width; x++) - { - for (int y = 0; y < Height; y++) - { - uint32_t r = PngPalette[src[x + y * Width] * 3 + 0]; - uint32_t g = PngPalette[src[x + y * Width] * 3 + 1]; - uint32_t b = PngPalette[src[x + y * Width] * 3 + 2]; - PixelsBgra[x * Height + y] = 0xff000000 | (r << 16) | (g << 8) | b; - } - } - } - else - { - for (int x = 0; x < Width; x++) - { - for (int y = 0; y < Height; y++) - { - uint32_t gray = src[x + y * Width]; - PixelsBgra[x * Height + y] = 0xff000000 | (gray << 16) | (gray << 8) | gray; - } - } - } - } - else /* RGB and/or Alpha present */ - { - int bytesPerPixel = ColorType == 2 ? 3 : ColorType == 4 ? 2 : 4; - BYTE *tempix = new BYTE[Width * Height * bytesPerPixel]; - BYTE *in; - uint32_t *out; - int x, y, pitch, backstep; - - M_ReadIDAT (lump, tempix, Width, Height, Width*bytesPerPixel, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); - in = tempix; - out = PixelsBgra.data(); - - // Convert from source format to paletted, column-major. - // Formats with alpha maps are reduced to only 1 bit of alpha. - switch (ColorType) - { - case 2: // RGB - pitch = Width * 3; - backstep = Height * pitch - 3; - for (x = Width; x > 0; --x) - { - for (y = Height; y > 0; --y) - { - if (!HaveTrans) - { - *out++ = 0xff000000 | (((uint32_t)in[0]) << 16) | (((uint32_t)in[1]) << 8) | ((uint32_t)in[2]); - } - else - { - if (in[0] == NonPaletteTrans[0] && - in[1] == NonPaletteTrans[1] && - in[2] == NonPaletteTrans[2]) - { - *out++ = 0; - } - else - { - *out++ = 0xff000000 | (((uint32_t)in[0]) << 16) | (((uint32_t)in[1]) << 8) | ((uint32_t)in[2]); - } - } - in += pitch; - } - in -= backstep; - } - break; - - case 4: // Grayscale + Alpha - pitch = Width * 2; - backstep = Height * pitch - 2; - for (x = Width; x > 0; --x) - { - for (y = Height; y > 0; --y) - { - // output as premultiplied alpha - uint32_t alpha = in[1]; - uint32_t gray = (in[0] * alpha + 127) / 255; - *out++ = (alpha << 24) | (gray << 16) | (gray << 8) | gray; - in += pitch; - } - in -= backstep; - } - break; - - case 6: // RGB + Alpha - pitch = Width * 4; - backstep = Height * pitch - 4; - for (x = Width; x > 0; --x) - { - for (y = Height; y > 0; --y) - { - // output as premultiplied alpha - uint32_t alpha = in[3]; - uint32_t red = (in[0] * alpha + 127) / 255; - uint32_t green = (in[1] * alpha + 127) / 255; - uint32_t blue = (in[2] * alpha + 127) / 255; - *out++ = (alpha << 24) | (red << 16) | (green << 8) | blue; - in += pitch; - } - in -= backstep; - } - break; - } - delete[] tempix; - } - } - delete lump; - GenerateBgraMipmaps(); -} - //=========================================================================== // // FPNGTexture::CopyTrueColorPixels diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 1602236170..7dfe04b230 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -194,21 +194,15 @@ const uint32_t *FTexture::GetColumnBgra(unsigned int column, const Span **spans_ const uint32_t *FTexture::GetPixelsBgra() { - if (PixelsBgra.empty()) + if (PixelsBgra.empty() || CheckModified()) { - GetColumn(0, nullptr); - const BYTE *indices = GetPixels(); - if (indices == nullptr) + if (!GetColumn(0, nullptr)) return nullptr; - CreatePixelsBgraWithMipmaps(); - for (int i = 0; i < Width * Height; i++) - { - if (indices[i] != 0) - PixelsBgra[i] = 0xff000000 | GPalette.BaseColors[indices[i]].d; - else - PixelsBgra[i] = 0; - } - GenerateBgraMipmaps(); + + FBitmap bitmap; + bitmap.Create(GetWidth(), GetHeight()); + CopyTrueColorPixels(&bitmap, 0, 0); + GenerateBgraFromBitmap(bitmap); } return PixelsBgra.data(); } @@ -356,6 +350,32 @@ void FTexture::FreeSpans (Span **spans) const M_Free (spans); } +void FTexture::GenerateBgraFromBitmap(const FBitmap &bitmap) +{ + CreatePixelsBgraWithMipmaps(); + + // Transpose and premultiply alpha + const uint32_t *src = (const uint32_t *)bitmap.GetPixels(); + uint32_t *dest = PixelsBgra.data(); + for (int x = 0; x < Width; x++) + { + for (int y = 0; y < Height; y++) + { + uint32_t p = src[x + y * Width]; + uint32_t red = RPART(p); + uint32_t green = GPART(p); + uint32_t blue = BPART(p); + uint32_t alpha = APART(p); + red = (red * alpha + 127) / 255; + green = (green * alpha + 127) / 255; + blue = (blue * alpha + 127) / 255; + dest[y + x * Height] = (alpha << 24) | (red << 16) | (green << 8) | blue; + } + } + + GenerateBgraMipmaps(); +} + void FTexture::CreatePixelsBgraWithMipmaps() { int levels = MipmapLevels(); diff --git a/src/textures/textures.h b/src/textures/textures.h index ff1093a49d..e5ecdc6797 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -274,6 +274,7 @@ protected: std::vector PixelsBgra; + void GenerateBgraFromBitmap(const FBitmap &bitmap); void CreatePixelsBgraWithMipmaps(); void GenerateBgraMipmaps(); void GenerateBgraMipmapsFast(); diff --git a/src/textures/warptexture.cpp b/src/textures/warptexture.cpp index 0d18ab58f4..91c7b9fc43 100644 --- a/src/textures/warptexture.cpp +++ b/src/textures/warptexture.cpp @@ -39,6 +39,7 @@ #include "r_utility.h" #include "textures/textures.h" #include "warpbuffer.h" +#include "v_palette.h" FWarpTexture::FWarpTexture (FTexture *source, int warptype) @@ -96,13 +97,20 @@ const BYTE *FWarpTexture::GetPixels () const uint32_t *FWarpTexture::GetPixelsBgra() { DWORD time = r_FrameTime; - if (Pixels == NULL || time != GenTime) { MakeTexture(time); - PixelsBgra.clear(); + CreatePixelsBgraWithMipmaps(); + for (int i = 0; i < Width * Height; i++) + { + if (Pixels[i] != 0) + PixelsBgra[i] = 0xff000000 | GPalette.BaseColors[Pixels[i]].d; + else + PixelsBgra[i] = 0; + } + GenerateBgraMipmapsFast(); } - return FTexture::GetPixelsBgra(); + return PixelsBgra.data(); } const BYTE *FWarpTexture::GetColumn (unsigned int column, const Span **spans_out)