Change GetPixelsBgra to use CopyTrueColorPixels

This commit is contained in:
Magnus Norddahl 2016-08-06 22:59:16 +02:00
parent 21390e91b8
commit 7000d0ccf9
7 changed files with 45 additions and 298 deletions

View file

@ -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)

View file

@ -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.

View file

@ -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();
}
//===========================================================================
//

View file

@ -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

View file

@ -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();

View file

@ -274,6 +274,7 @@ protected:
std::vector<uint32_t> PixelsBgra;
void GenerateBgraFromBitmap(const FBitmap &bitmap);
void CreatePixelsBgraWithMipmaps();
void GenerateBgraMipmaps();
void GenerateBgraMipmapsFast();

View file

@ -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;
}
return FTexture::GetPixelsBgra();
GenerateBgraMipmapsFast();
}
return PixelsBgra.data();
}
const BYTE *FWarpTexture::GetColumn (unsigned int column, const Span **spans_out)