mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-17 17:41:23 +00:00
- Fixed: FTexture::~FTexture() must destroy the associated native texture
if present. - Modified GZDoom's true color texture copy functions and added them to generate 32 bit D3D textures. Paletted TGAs and PCXs are also handled this way but I don't think these 2 formats are worth some more special handling. (Question: Is it worth it to implement special handling for paletted PNGs so that they are used as 8 bit textures internally?) SVN r608 (trunk)
This commit is contained in:
parent
457976d88d
commit
28db2d9f15
12 changed files with 773 additions and 21 deletions
|
@ -1,4 +1,12 @@
|
||||||
December 20, 2007 (Changes by Graf Zahl)
|
December 20, 2007 (Changes by Graf Zahl)
|
||||||
|
- Fixed: FTexture::~FTexture() must destroy the associated native texture
|
||||||
|
if present.
|
||||||
|
- Modified GZDoom's true color texture copy functions and added them
|
||||||
|
to generate 32 bit D3D textures. Paletted TGAs and PCXs are also handled
|
||||||
|
this way but I don't think these 2 formats are worth some more special
|
||||||
|
handling.
|
||||||
|
(Question: Is it worth it to implement special handling for paletted PNGs
|
||||||
|
so that they are used as 8 bit textures internally?)
|
||||||
- Fixed: DCanvas::Blit unlocked the destination twice instead of unlocking
|
- Fixed: DCanvas::Blit unlocked the destination twice instead of unlocking
|
||||||
both dest and src. Also changed this function so that it is owned by the
|
both dest and src. Also changed this function so that it is owned by the
|
||||||
destination canvas of the operation which is necessary if it needs to
|
destination canvas of the operation which is necessary if it needs to
|
||||||
|
|
14
src/r_data.h
14
src/r_data.h
|
@ -85,9 +85,12 @@ public:
|
||||||
|
|
||||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||||
const BYTE *GetPixels ();
|
const BYTE *GetPixels ();
|
||||||
|
FTextureFormat GetFormat();
|
||||||
void Unload ();
|
void Unload ();
|
||||||
virtual void SetFrontSkyLayer ();
|
virtual void SetFrontSkyLayer ();
|
||||||
|
|
||||||
|
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BYTE *Pixels;
|
BYTE *Pixels;
|
||||||
Span **Spans;
|
Span **Spans;
|
||||||
|
@ -237,6 +240,8 @@ public:
|
||||||
const BYTE *GetPixels ();
|
const BYTE *GetPixels ();
|
||||||
void Unload ();
|
void Unload ();
|
||||||
FTextureFormat GetFormat ();
|
FTextureFormat GetFormat ();
|
||||||
|
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
|
||||||
|
bool UseBasePalette();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -312,6 +317,8 @@ public:
|
||||||
const BYTE *GetPixels ();
|
const BYTE *GetPixels ();
|
||||||
void Unload ();
|
void Unload ();
|
||||||
FTextureFormat GetFormat ();
|
FTextureFormat GetFormat ();
|
||||||
|
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
|
||||||
|
bool UseBasePalette();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -361,6 +368,9 @@ public:
|
||||||
void Unload ();
|
void Unload ();
|
||||||
FTextureFormat GetFormat ();
|
FTextureFormat GetFormat ();
|
||||||
|
|
||||||
|
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
|
||||||
|
bool UseBasePalette();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int SourceLump;
|
int SourceLump;
|
||||||
BYTE *Pixels;
|
BYTE *Pixels;
|
||||||
|
@ -412,6 +422,10 @@ public:
|
||||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||||
const BYTE *GetPixels ();
|
const BYTE *GetPixels ();
|
||||||
void Unload ();
|
void Unload ();
|
||||||
|
FTextureFormat GetFormat ();
|
||||||
|
|
||||||
|
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
|
||||||
|
bool UseBasePalette();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int SourceLump;
|
int SourceLump;
|
||||||
|
|
|
@ -665,6 +665,9 @@ public:
|
||||||
// Returns the whole texture, stored in column-major order
|
// Returns the whole texture, stored in column-major order
|
||||||
virtual const BYTE *GetPixels () = 0;
|
virtual const BYTE *GetPixels () = 0;
|
||||||
|
|
||||||
|
virtual int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
|
||||||
|
virtual bool UseBasePalette();
|
||||||
|
|
||||||
virtual void Unload () = 0;
|
virtual void Unload () = 0;
|
||||||
|
|
||||||
// Returns the native pixel format for this image
|
// Returns the native pixel format for this image
|
||||||
|
@ -677,7 +680,7 @@ public:
|
||||||
void KillNative();
|
void KillNative();
|
||||||
|
|
||||||
// Fill the native texture buffer with pixel data for this image
|
// Fill the native texture buffer with pixel data for this image
|
||||||
virtual void FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt);
|
virtual void FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt);
|
||||||
|
|
||||||
int GetWidth () { return Width; }
|
int GetWidth () { return Width; }
|
||||||
int GetHeight () { return Height; }
|
int GetHeight () { return Height; }
|
||||||
|
|
|
@ -323,3 +323,91 @@ void FJPEGTexture::MakeTexture ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FJPEGTexture::CopyTrueColorPixels
|
||||||
|
//
|
||||||
|
// Preserves the full color information (unlike software mode)
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int FJPEGTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
|
||||||
|
{
|
||||||
|
PalEntry pe[256];
|
||||||
|
|
||||||
|
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
||||||
|
JSAMPLE *buff = NULL;
|
||||||
|
|
||||||
|
jpeg_decompress_struct cinfo;
|
||||||
|
jpeg_error_mgr jerr;
|
||||||
|
|
||||||
|
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 yc = 0;
|
||||||
|
buff = new BYTE[cinfo.output_height * cinfo.output_width * cinfo.output_components];
|
||||||
|
|
||||||
|
|
||||||
|
while (cinfo.output_scanline < cinfo.output_height)
|
||||||
|
{
|
||||||
|
BYTE * ptr = buff + cinfo.output_width * cinfo.output_components * yc;
|
||||||
|
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||||
|
yc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cinfo.out_color_space)
|
||||||
|
{
|
||||||
|
case JCS_RGB:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||||
|
3, cinfo.output_width * cinfo.output_components, CF_RGB);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JCS_GRAYSCALE:
|
||||||
|
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
|
||||||
|
screen->CopyPixelData(buffer, buf_width, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||||
|
1, cinfo.output_width, pe);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JCS_CMYK:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||||
|
4, cinfo.output_width * cinfo.output_components, CF_CMYK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
}
|
||||||
|
catch(int)
|
||||||
|
{
|
||||||
|
Printf (TEXTCOLOR_ORANGE " in JPEG texture %s\n", Name);
|
||||||
|
}
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
if (buff != NULL) delete [] buff;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool FJPEGTexture::UseBasePalette()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -371,6 +371,40 @@ void FMultiPatchTexture::CheckForHacks ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FMultipatchTexture::CopyTrueColorPixels
|
||||||
|
//
|
||||||
|
// Preserves the palettes of each individual patch
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int FMultiPatchTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
|
||||||
|
{
|
||||||
|
int retv = -1;
|
||||||
|
|
||||||
|
for(int i=0;i<NumParts;i++)
|
||||||
|
{
|
||||||
|
int ret = Parts[i].Texture->CopyTrueColorPixels(buffer, buf_width, buf_height,
|
||||||
|
x+Parts[i].OriginX, y+Parts[i].OriginY);
|
||||||
|
|
||||||
|
if (ret > retv) retv = ret;
|
||||||
|
}
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
FTextureFormat FMultiPatchTexture::GetFormat()
|
||||||
|
{
|
||||||
|
if (NumParts == 1) return Parts[0].Texture->GetFormat();
|
||||||
|
|
||||||
|
for(int i=0;i<NumParts;i++)
|
||||||
|
{
|
||||||
|
if (!Parts[i].Texture->UseBasePalette()) return TEX_RGB;
|
||||||
|
}
|
||||||
|
return TEX_Pal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int patcheslump, int firstdup, bool texture1)
|
void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int patcheslump, int firstdup, bool texture1)
|
||||||
{
|
{
|
||||||
FPatchLookup *patchlookup;
|
FPatchLookup *patchlookup;
|
||||||
|
|
|
@ -111,6 +111,12 @@ void FPCXTexture::Unload ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FTextureFormat FPCXTexture::GetFormat()
|
||||||
|
{
|
||||||
|
return TEX_RGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const BYTE *FPCXTexture::GetColumn (unsigned int column, const Span **spans_out)
|
const BYTE *FPCXTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||||
{
|
{
|
||||||
if (Pixels == NULL)
|
if (Pixels == NULL)
|
||||||
|
@ -404,3 +410,88 @@ void FPCXTexture::MakeTexture()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FPCXTexture::CopyTrueColorPixels
|
||||||
|
//
|
||||||
|
// Preserves the full color information (unlike software mode)
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int FPCXTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
|
||||||
|
{
|
||||||
|
PalEntry pe[256];
|
||||||
|
PCXHeader header;
|
||||||
|
int bitcount;
|
||||||
|
BYTE * Pixels;
|
||||||
|
|
||||||
|
FWadLump lump = Wads.OpenLumpNum(SourceLump);
|
||||||
|
|
||||||
|
lump.Read(&header, sizeof(header));
|
||||||
|
|
||||||
|
bitcount = header.bitsPerPixel * header.numColorPlanes;
|
||||||
|
|
||||||
|
if (bitcount < 24)
|
||||||
|
{
|
||||||
|
Pixels = new BYTE[Width*Height];
|
||||||
|
if (bitcount < 8)
|
||||||
|
{
|
||||||
|
for (int i=0;i<16;i++)
|
||||||
|
{
|
||||||
|
pe[i] = PalEntry(header.palette[i*3],header.palette[i*3+1],header.palette[i*3+2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bitcount)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 1:
|
||||||
|
ReadPCX1bit (Pixels, lump, &header);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
ReadPCX4bits (Pixels, lump, &header);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bitcount == 8)
|
||||||
|
{
|
||||||
|
BYTE c;
|
||||||
|
lump.Seek(-769, SEEK_END);
|
||||||
|
lump >> c;
|
||||||
|
c=0x0c; // Apparently there's many non-compliant PCXs out there...
|
||||||
|
if (c !=0x0c)
|
||||||
|
{
|
||||||
|
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
|
||||||
|
}
|
||||||
|
else for(int i=0;i<256;i++)
|
||||||
|
{
|
||||||
|
BYTE r,g,b;
|
||||||
|
lump >> r >> g >> b;
|
||||||
|
pe[i] = PalEntry(r,g,b);
|
||||||
|
}
|
||||||
|
lump.Seek(sizeof(header), SEEK_SET);
|
||||||
|
ReadPCX8bits (Pixels, lump, &header);
|
||||||
|
}
|
||||||
|
screen->CopyPixelData(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 1, Width, pe);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pixels = new BYTE[Width*Height * 3];
|
||||||
|
BYTE * row = buffer;
|
||||||
|
ReadPCX24bits (Pixels, lump, &header, 3);
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 3, Width*3, CF_RGB);
|
||||||
|
}
|
||||||
|
delete [] Pixels;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool FPCXTexture::UseBasePalette()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -438,3 +438,99 @@ void FPNGTexture::MakeTexture ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FPNGTexture::CopyTrueColorPixels
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int FPNGTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
|
||||||
|
{
|
||||||
|
// Parse pre-IDAT chunks. I skip the CRCs. Is that bad?
|
||||||
|
PalEntry pe[256];
|
||||||
|
DWORD len, id;
|
||||||
|
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
||||||
|
static char bpp[]={1, 0, 3, 1, 2, 0, 4};
|
||||||
|
int pixwidth = Width * bpp[ColorType];
|
||||||
|
int transpal=false;
|
||||||
|
|
||||||
|
lump.Seek (33, SEEK_SET);
|
||||||
|
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
|
||||||
|
|
||||||
|
lump >> len >> id;
|
||||||
|
while (id != MAKE_ID('I','D','A','T') && id != MAKE_ID('I','E','N','D'))
|
||||||
|
{
|
||||||
|
len = BigLong((unsigned int)len);
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
lump.Seek (len, SEEK_CUR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAKE_ID('P','L','T','E'):
|
||||||
|
for(int i=0;i<PaletteSize;i++)
|
||||||
|
lump >> pe[i].r >> pe[i].g >> pe[i].b;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAKE_ID('t','R','N','S'):
|
||||||
|
for(DWORD i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
lump >> pe[i].a;
|
||||||
|
pe[i].a=255-pe[i].a; // use inverse alpha so the default palette can be used unchanged
|
||||||
|
if (pe[i].a!=0 && pe[i].a!=255) transpal = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lump >> len >> len; // Skip CRC
|
||||||
|
id = MAKE_ID('I','E','N','D');
|
||||||
|
lump >> id;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE * Pixels = new BYTE[pixwidth * Height];
|
||||||
|
|
||||||
|
lump.Seek (StartOfIDAT, SEEK_SET);
|
||||||
|
lump >> len >> id;
|
||||||
|
M_ReadIDAT (&lump, Pixels, Width, Height, pixwidth, BitDepth, ColorType, Interlace, BigLong((unsigned int)len));
|
||||||
|
|
||||||
|
switch (ColorType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 3:
|
||||||
|
screen->CopyPixelData(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 1, Width, pe);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 3, pixwidth, CF_RGB);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 2, pixwidth, CF_IA);
|
||||||
|
transpal = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, Pixels, Width, Height, 4, pixwidth, CF_RGBA);
|
||||||
|
transpal = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
delete[] Pixels;
|
||||||
|
return transpal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// This doesn't check if the palette is identical with the base palette
|
||||||
|
// I don't think it's worth the hassle because it's only of importance
|
||||||
|
// when compositing multipatch textures.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool FPNGTexture::UseBasePalette()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -125,6 +125,7 @@ FTexture::FTexture ()
|
||||||
|
|
||||||
FTexture::~FTexture ()
|
FTexture::~FTexture ()
|
||||||
{
|
{
|
||||||
|
KillNative();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FTexture::CheckModified ()
|
bool FTexture::CheckModified ()
|
||||||
|
@ -428,19 +429,19 @@ void FTexture::KillNative()
|
||||||
// color data. Note that the buffer expects row-major data, since that's
|
// 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
|
// 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.
|
// need to be used by any of Doom's column drawing routines.
|
||||||
void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt)
|
void FTexture::FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt)
|
||||||
{
|
{
|
||||||
const BYTE *pix;
|
const BYTE *pix;
|
||||||
int x, y, w, h, stride;
|
int x, y, w, h, stride;
|
||||||
|
|
||||||
w = GetWidth();
|
w = GetWidth();
|
||||||
h = GetHeight();
|
h = GetHeight();
|
||||||
pix = GetPixels();
|
|
||||||
|
|
||||||
switch (fmt)
|
switch (fmt)
|
||||||
{
|
{
|
||||||
case TEX_Pal:
|
case TEX_Pal:
|
||||||
case TEX_Gray:
|
case TEX_Gray:
|
||||||
|
pix = GetPixels();
|
||||||
stride = pitch - w;
|
stride = pitch - w;
|
||||||
for (y = 0; y < h; ++y)
|
for (y = 0; y < h; ++y)
|
||||||
{
|
{
|
||||||
|
@ -456,23 +457,7 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TEX_RGB:
|
case TEX_RGB:
|
||||||
stride = pitch - w * 4;
|
CopyTrueColorPixels(buff, pitch, height, 0, 0);
|
||||||
for (y = 0; y < h; ++y)
|
|
||||||
{
|
|
||||||
const BYTE *pix2 = pix;
|
|
||||||
for (x = 0; x < w; ++x)
|
|
||||||
{
|
|
||||||
const PalEntry *pal = &GPalette.BaseColors[*pix2];
|
|
||||||
buff[0] = pal->b;
|
|
||||||
buff[1] = pal->g;
|
|
||||||
buff[2] = pal->r;
|
|
||||||
buff[3] = pal->a;
|
|
||||||
buff += 4;
|
|
||||||
pix2 += h;
|
|
||||||
}
|
|
||||||
pix++;
|
|
||||||
buff += stride;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -480,6 +465,37 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FTexture::CopyTrueColorPixels
|
||||||
|
//
|
||||||
|
// this is the generic case that can handle
|
||||||
|
// any properly implemented texture for software rendering.
|
||||||
|
// Its drawback is that it is limited to the base palette which is
|
||||||
|
// why all classes that handle different palettes should subclass this
|
||||||
|
// method
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int FTexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
|
||||||
|
{
|
||||||
|
PalEntry * palette = screen->GetPalette();
|
||||||
|
palette[0].a=255; // temporarily modify the first color's alpha
|
||||||
|
screen->CopyPixelData(buffer, buf_width, buf_height, x, y,
|
||||||
|
GetPixels(), Width, Height, Height, 1,
|
||||||
|
palette);
|
||||||
|
|
||||||
|
palette[0].a=0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FTexture::UseBasePalette()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FDummyTexture::FDummyTexture ()
|
FDummyTexture::FDummyTexture ()
|
||||||
{
|
{
|
||||||
Width = 64;
|
Width = 64;
|
||||||
|
|
|
@ -378,5 +378,159 @@ void FTGATexture::MakeTexture ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FTGATexture::CopyTrueColorPixels
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int FTGATexture::CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y)
|
||||||
|
{
|
||||||
|
PalEntry pe[256];
|
||||||
|
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
||||||
|
TGAHeader hdr;
|
||||||
|
WORD w;
|
||||||
|
BYTE r,g,b,a;
|
||||||
|
BYTE * sbuffer;
|
||||||
|
int transval = 0;
|
||||||
|
|
||||||
|
lump.Read(&hdr, sizeof(hdr));
|
||||||
|
lump.Seek(hdr.id_len, SEEK_CUR);
|
||||||
|
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
hdr.width = LittleShort(hdr.width);
|
||||||
|
hdr.height = LittleShort(hdr.height);
|
||||||
|
hdr.cm_first = LittleShort(hdr.cm_first);
|
||||||
|
hdr.cm_length = LittleShort(hdr.cm_length);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (hdr.has_cm)
|
||||||
|
{
|
||||||
|
memset(pe, 0, 256*sizeof(PalEntry));
|
||||||
|
for (int i = hdr.cm_first; i < hdr.cm_first + hdr.cm_length && i < 256; i++)
|
||||||
|
{
|
||||||
|
switch (hdr.cm_size)
|
||||||
|
{
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
lump >> w;
|
||||||
|
r = (w & 0x001F) << 3;
|
||||||
|
g = (w & 0x03E0) >> 2;
|
||||||
|
b = (w & 0x7C00) >> 7;
|
||||||
|
a = 255;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
lump >> b >> g >> r;
|
||||||
|
a=255;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
lump >> b >> g >> r >> a;
|
||||||
|
if ((hdr.img_desc&15)!=8) a=255;
|
||||||
|
else if (a!=0 && a!=255) transval = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // should never happen
|
||||||
|
r=g=b=a=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pe[i] = PalEntry(255-a, r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Size = Width * Height * (hdr.bpp>>3);
|
||||||
|
sbuffer = new BYTE[Size];
|
||||||
|
|
||||||
|
if (hdr.img_type < 4) // uncompressed
|
||||||
|
{
|
||||||
|
lump.Read(sbuffer, Size);
|
||||||
|
}
|
||||||
|
else // compressed
|
||||||
|
{
|
||||||
|
ReadCompressed(lump, sbuffer, hdr.bpp>>3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE * ptr = sbuffer;
|
||||||
|
int step_x = (hdr.bpp>>3);
|
||||||
|
int Pitch = Width * step_x;
|
||||||
|
|
||||||
|
if (hdr.img_desc&32)
|
||||||
|
{
|
||||||
|
ptr += (Width-1) * step_x;
|
||||||
|
step_x =- step_x;
|
||||||
|
}
|
||||||
|
if (!(hdr.img_desc&64))
|
||||||
|
{
|
||||||
|
ptr += (Height-1) * Pitch;
|
||||||
|
Pitch = -Pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (hdr.img_type & 7)
|
||||||
|
{
|
||||||
|
case 1: // paletted
|
||||||
|
screen->CopyPixelData(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, pe);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // RGB
|
||||||
|
switch (hdr.bpp)
|
||||||
|
{
|
||||||
|
case 15:
|
||||||
|
case 16:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_RGB555);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
if ((hdr.img_desc&15)!=8) // 32 bits without a valid alpha channel
|
||||||
|
{
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_BGRA);
|
||||||
|
transval = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // Grayscale
|
||||||
|
switch (hdr.bpp)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // gray map
|
||||||
|
screen->CopyPixelData(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, pe);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
screen->CopyPixelDataRGB(buffer, buf_width, buf_height, x, y, ptr, Width, Height, step_x, Pitch, CF_I16);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete [] sbuffer;
|
||||||
|
return transval;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
bool FTGATexture::UseBasePalette()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
131
src/v_video.cpp
131
src/v_video.cpp
|
@ -797,6 +797,137 @@ FNativeTexture *DFrameBuffer::CreatePalette(const PalEntry *pal)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// multi-format pixel copy with colormap application
|
||||||
|
// requires one of the previously defined conversion classes to work
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
template<class T>
|
||||||
|
void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step)
|
||||||
|
{
|
||||||
|
for(int i=0;i<count;i++)
|
||||||
|
{
|
||||||
|
pout[0]=T::R(pin);
|
||||||
|
pout[1]=T::G(pin);
|
||||||
|
pout[2]=T::B(pin);
|
||||||
|
pout[3]=T::A(pin);
|
||||||
|
pout+=4;
|
||||||
|
pin+=step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int count, int step);
|
||||||
|
|
||||||
|
static CopyFunc copyfuncs[]={
|
||||||
|
iCopyColors<cRGB>,
|
||||||
|
iCopyColors<cRGBA>,
|
||||||
|
iCopyColors<cIA>,
|
||||||
|
iCopyColors<cCMYK>,
|
||||||
|
iCopyColors<cBGR>,
|
||||||
|
iCopyColors<cBGRA>,
|
||||||
|
iCopyColors<cI16>,
|
||||||
|
iCopyColors<cRGB555>,
|
||||||
|
iCopyColors<cPalEntry>
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Clips the copy area for CopyPixelData functions
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
bool DFrameBuffer::ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy,
|
||||||
|
const BYTE *&patch, int &srcwidth, int &srcheight, int step_x, int step_y)
|
||||||
|
{
|
||||||
|
// clip source rectangle to destination
|
||||||
|
if (originx<0)
|
||||||
|
{
|
||||||
|
srcwidth+=originx;
|
||||||
|
patch-=originx*step_x;
|
||||||
|
originx=0;
|
||||||
|
if (srcwidth<=0) return false;
|
||||||
|
}
|
||||||
|
if (originx+srcwidth>texwidth)
|
||||||
|
{
|
||||||
|
srcwidth=texwidth-originx;
|
||||||
|
if (srcwidth<=0) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originy<0)
|
||||||
|
{
|
||||||
|
srcheight+=originy;
|
||||||
|
patch-=originy*step_y;
|
||||||
|
originy=0;
|
||||||
|
if (srcheight<=0) return false;
|
||||||
|
}
|
||||||
|
if (originy+srcheight>texheight)
|
||||||
|
{
|
||||||
|
srcheight=texheight-originy;
|
||||||
|
if (srcheight<=0) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// True Color texture copy function
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
void DFrameBuffer::CopyPixelDataRGB(BYTE * buffer, int texwidth, int texheight, int originx, int originy,
|
||||||
|
const BYTE * patch, int srcwidth, int srcheight, int step_x, int step_y,
|
||||||
|
int ct)
|
||||||
|
{
|
||||||
|
if (ClipCopyPixelRect(texwidth, texheight, originx, originy, patch, srcwidth, srcheight, step_x, step_y))
|
||||||
|
{
|
||||||
|
buffer+=4*originx + 4*texwidth*originy;
|
||||||
|
for (int y=0;y<srcheight;y++)
|
||||||
|
{
|
||||||
|
copyfuncs[ct](&buffer[4*y*texwidth], &patch[y*step_y], srcwidth, step_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Paletted to True Color texture copy function
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
void DFrameBuffer::CopyPixelData(BYTE * buffer, int texwidth, int texheight, int originx, int originy,
|
||||||
|
const BYTE * patch, int srcwidth, int srcheight,
|
||||||
|
int step_x, int step_y, PalEntry * palette)
|
||||||
|
{
|
||||||
|
int x,y,pos;
|
||||||
|
|
||||||
|
if (ClipCopyPixelRect(texwidth, texheight, originx, originy, patch, srcwidth, srcheight, step_x, step_y))
|
||||||
|
{
|
||||||
|
buffer+=4*originx + 4*texwidth*originy;
|
||||||
|
|
||||||
|
for (y=0;y<srcheight;y++)
|
||||||
|
{
|
||||||
|
pos=4*(y*texwidth);
|
||||||
|
for (x=0;x<srcwidth;x++,pos+=4)
|
||||||
|
{
|
||||||
|
int v=(unsigned char)patch[y*step_y+x*step_x];
|
||||||
|
if (palette[v].a==0)
|
||||||
|
{
|
||||||
|
buffer[pos]=palette[v].r;
|
||||||
|
buffer[pos+1]=palette[v].g;
|
||||||
|
buffer[pos+2]=palette[v].b;
|
||||||
|
buffer[pos+3]=255-palette[v].a;
|
||||||
|
}
|
||||||
|
else if (palette[v].a!=255)
|
||||||
|
{
|
||||||
|
buffer[pos ] = (buffer[pos ] * palette[v].a + palette[v].r * (1-palette[v].a)) / 255;
|
||||||
|
buffer[pos+1] = (buffer[pos+1] * palette[v].a + palette[v].g * (1-palette[v].a)) / 255;
|
||||||
|
buffer[pos+2] = (buffer[pos+2] * palette[v].a + palette[v].b * (1-palette[v].a)) / 255;
|
||||||
|
buffer[pos+3] = clamp<int>(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-palette[v].a))/255, 0, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FNativeTexture::~FNativeTexture()
|
FNativeTexture::~FNativeTexture()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
117
src/v_video.h
117
src/v_video.h
|
@ -316,6 +316,16 @@ public:
|
||||||
// Create a palette texture from a 256-entry palette.
|
// Create a palette texture from a 256-entry palette.
|
||||||
virtual FNativeTexture *CreatePalette(const PalEntry *pal);
|
virtual FNativeTexture *CreatePalette(const PalEntry *pal);
|
||||||
|
|
||||||
|
// texture copy functions
|
||||||
|
virtual void CopyPixelDataRGB(BYTE * buffer, int texwidth, int texheight, int originx, int originy,
|
||||||
|
const BYTE * patch, int pix_width, int pix_height, int step_x, int step_y,
|
||||||
|
int ct);
|
||||||
|
|
||||||
|
virtual void CopyPixelData(BYTE * buffer, int texwidth, int texheight, int originx, int originy,
|
||||||
|
const BYTE * patch, int pix_width, int pix_height,
|
||||||
|
int step_x, int step_y, PalEntry * palette);
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
virtual void PaletteChanged () = 0;
|
virtual void PaletteChanged () = 0;
|
||||||
virtual int QueryNewPalette () = 0;
|
virtual int QueryNewPalette () = 0;
|
||||||
|
@ -327,6 +337,10 @@ protected:
|
||||||
|
|
||||||
DFrameBuffer () {}
|
DFrameBuffer () {}
|
||||||
|
|
||||||
|
bool ClipCopyPixelRect(int texwidth, int texheight, int &originx, int &originy,
|
||||||
|
const BYTE *&patch, int &srcwidth, int &srcheight, int step_x, int step_y);
|
||||||
|
|
||||||
|
|
||||||
int RateX;
|
int RateX;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -385,4 +399,107 @@ extern "C" void ASM_PatchPitch (void);
|
||||||
int CheckRatio (int width, int height);
|
int CheckRatio (int width, int height);
|
||||||
extern const int BaseRatioSizes[5][4];
|
extern const int BaseRatioSizes[5][4];
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// True color conversion classes for the different pixel formats
|
||||||
|
// used by the supported texture formats
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
struct cRGB
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[2]; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return 255; }
|
||||||
|
static int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cRGBA
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[2]; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return p[3]; }
|
||||||
|
static int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cIA
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return p[1]; }
|
||||||
|
static int Gray(const unsigned char * p) { return p[0]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cCMYK
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[3] - (((256-p[0])*p[3]) >> 8); }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[3] - (((256-p[1])*p[3]) >> 8); }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[3] - (((256-p[2])*p[3]) >> 8); }
|
||||||
|
static unsigned char A(const unsigned char * p) { return 255; }
|
||||||
|
static int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cBGR
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[2]; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return 255; }
|
||||||
|
static int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cBGRA
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[2]; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[0]; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return p[3]; }
|
||||||
|
static int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cI16
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return p[1]; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return 255; }
|
||||||
|
static int Gray(const unsigned char * p) { return p[1]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cRGB555
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return (((*(WORD*)p)&0x1f)<<3); }
|
||||||
|
static unsigned char G(const unsigned char * p) { return (((*(WORD*)p)&0x3e0)>>2); }
|
||||||
|
static unsigned char B(const unsigned char * p) { return (((*(WORD*)p)&0x7c00)>>7); }
|
||||||
|
static unsigned char A(const unsigned char * p) { return p[1]; }
|
||||||
|
static int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cPalEntry
|
||||||
|
{
|
||||||
|
static unsigned char R(const unsigned char * p) { return ((PalEntry*)p)->r; }
|
||||||
|
static unsigned char G(const unsigned char * p) { return ((PalEntry*)p)->g; }
|
||||||
|
static unsigned char B(const unsigned char * p) { return ((PalEntry*)p)->b; }
|
||||||
|
static unsigned char A(const unsigned char * p) { return ((PalEntry*)p)->a; }
|
||||||
|
static int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ColorType
|
||||||
|
{
|
||||||
|
CF_RGB,
|
||||||
|
CF_RGBA,
|
||||||
|
CF_IA,
|
||||||
|
CF_CMYK,
|
||||||
|
CF_BGR,
|
||||||
|
CF_BGRA,
|
||||||
|
CF_I16,
|
||||||
|
CF_RGB555,
|
||||||
|
CF_PalEntry
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __V_VIDEO_H__
|
#endif // __V_VIDEO_H__
|
||||||
|
|
|
@ -1200,7 +1200,7 @@ bool D3DTex::Update()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
GameTex->FillBuffer((BYTE *)lrect.pBits, lrect.Pitch, ToTexFmt(desc.Format));
|
GameTex->FillBuffer((BYTE *)lrect.pBits, lrect.Pitch, rect.bottom, ToTexFmt(desc.Format));
|
||||||
Tex->UnlockRect(0);
|
Tex->UnlockRect(0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue