- 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:
Christoph Oelckers 2007-12-20 18:53:35 +00:00
parent 457976d88d
commit 28db2d9f15
12 changed files with 773 additions and 21 deletions

View file

@ -1,4 +1,12 @@
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
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

View file

@ -85,9 +85,12 @@ public:
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
const BYTE *GetPixels ();
FTextureFormat GetFormat();
void Unload ();
virtual void SetFrontSkyLayer ();
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
protected:
BYTE *Pixels;
Span **Spans;
@ -237,6 +240,8 @@ public:
const BYTE *GetPixels ();
void Unload ();
FTextureFormat GetFormat ();
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
bool UseBasePalette();
protected:
@ -312,6 +317,8 @@ public:
const BYTE *GetPixels ();
void Unload ();
FTextureFormat GetFormat ();
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
bool UseBasePalette();
protected:
@ -361,6 +368,9 @@ public:
void Unload ();
FTextureFormat GetFormat ();
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
bool UseBasePalette();
protected:
int SourceLump;
BYTE *Pixels;
@ -412,6 +422,10 @@ public:
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
const BYTE *GetPixels ();
void Unload ();
FTextureFormat GetFormat ();
int CopyTrueColorPixels(BYTE * buffer, int buf_width, int buf_height, int x, int y);
bool UseBasePalette();
protected:
int SourceLump;

View file

@ -664,6 +664,9 @@ public:
// Returns the whole texture, stored in column-major order
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;
@ -677,7 +680,7 @@ public:
void KillNative();
// 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 GetHeight () { return Height; }

View file

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

View file

@ -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)
{
FPatchLookup *patchlookup;

View file

@ -111,6 +111,12 @@ void FPCXTexture::Unload ()
}
}
FTextureFormat FPCXTexture::GetFormat()
{
return TEX_RGB;
}
const BYTE *FPCXTexture::GetColumn (unsigned int column, const Span **spans_out)
{
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;
}

View file

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

View file

@ -125,6 +125,7 @@ FTexture::FTexture ()
FTexture::~FTexture ()
{
KillNative();
}
bool FTexture::CheckModified ()
@ -428,19 +429,19 @@ void FTexture::KillNative()
// 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
// 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;
int x, y, w, h, stride;
w = GetWidth();
h = GetHeight();
pix = GetPixels();
switch (fmt)
{
case TEX_Pal:
case TEX_Gray:
pix = GetPixels();
stride = pitch - w;
for (y = 0; y < h; ++y)
{
@ -456,23 +457,7 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, FTextureFormat fmt)
break;
case TEX_RGB:
stride = pitch - w * 4;
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;
}
CopyTrueColorPixels(buff, pitch, height, 0, 0);
break;
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 ()
{
Width = 64;

View file

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

View file

@ -797,6 +797,137 @@ FNativeTexture *DFrameBuffer::CreatePalette(const PalEntry *pal)
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()
{
}

View file

@ -316,6 +316,16 @@ public:
// Create a palette texture from a 256-entry palette.
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
virtual void PaletteChanged () = 0;
virtual int QueryNewPalette () = 0;
@ -327,6 +337,10 @@ protected:
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;
private:
@ -385,4 +399,107 @@ extern "C" void ASM_PatchPitch (void);
int CheckRatio (int width, int height);
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__

View file

@ -1200,7 +1200,7 @@ bool D3DTex::Update()
{
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);
return true;
}