mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-25 13:31:07 +00:00
Change GetPixelsBgra to use CopyTrueColorPixels
This commit is contained in:
parent
21390e91b8
commit
7000d0ccf9
7 changed files with 45 additions and 298 deletions
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -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<BYTE> 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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -274,6 +274,7 @@ protected:
|
|||
|
||||
std::vector<uint32_t> PixelsBgra;
|
||||
|
||||
void GenerateBgraFromBitmap(const FBitmap &bitmap);
|
||||
void CreatePixelsBgraWithMipmaps();
|
||||
void GenerateBgraMipmaps();
|
||||
void GenerateBgraMipmapsFast();
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue