Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
818 lines
19 KiB
C++
818 lines
19 KiB
C++
#include "ProxyHeaders.hpp"
|
|
#include <imagelib\image.h>
|
|
#include <GameOs\PNG\png.h>
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
//
|
|
//############################################################################
|
|
//########################### TextureProxy ############################
|
|
//############################################################################
|
|
//
|
|
|
|
MemoryBlock*
|
|
TextureProxy::AllocatedMemory = NULL;
|
|
TextureProxy::ClassData*
|
|
TextureProxy::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::InitializeClass()
|
|
{
|
|
Verify(!AllocatedMemory);
|
|
AllocatedMemory =
|
|
new MemoryBlock(
|
|
sizeof(TextureProxy),
|
|
10,
|
|
10,
|
|
"TextureProxy"
|
|
);
|
|
Register_Object(AllocatedMemory);
|
|
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
TextureProxyClassID,
|
|
"TextureProxy",
|
|
GenericProxy::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
|
|
Unregister_Object(AllocatedMemory);
|
|
delete AllocatedMemory;
|
|
AllocatedMemory = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureProxy::TextureProxy(
|
|
ClassData *class_data,
|
|
TextureLibrary *library
|
|
):
|
|
GenericProxy(class_data),
|
|
libraryProxy(library)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(libraryProxy);
|
|
libraryProxy->AttachTextureProxy(this);
|
|
textureSize.x = textureSize.y = 0;
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureProxy::TextureProxy(
|
|
const char* name,
|
|
const Vector2DOf<int> &size,
|
|
TextureLibrary *library
|
|
):
|
|
GenericProxy(DefaultData),
|
|
libraryProxy(library),
|
|
textureName(name),
|
|
textureSize(size)
|
|
{
|
|
Check_Pointer(this);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
redDepth = greenDepth = blueDepth = alphaDepth = 0;
|
|
libraryProxy->AttachReference();
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureProxy::~TextureProxy()
|
|
{
|
|
Check_Object(this);
|
|
if (libraryProxy)
|
|
{
|
|
Check_Object(libraryProxy);
|
|
libraryProxy->DetachReference();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::Destroy()
|
|
{
|
|
Check_Object(this);
|
|
Verify(referenceCount == 1);
|
|
DetachReference();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
TextureProxy::IsEqualTo(TextureProxy *texture)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(texture);
|
|
|
|
//
|
|
//-----------------------------------------
|
|
// Make sure we aren't comparing to ourself
|
|
//-----------------------------------------
|
|
//
|
|
if (this == texture)
|
|
return true;
|
|
|
|
//
|
|
//------------------
|
|
// Compare the names
|
|
//------------------
|
|
//
|
|
MString filename_1;
|
|
if (GetName(&filename_1))
|
|
{
|
|
MString filename_2;
|
|
if (texture->GetName(&filename_2))
|
|
return filename_1 == filename_2;
|
|
return false;
|
|
}
|
|
return !texture->GetName(&filename_1);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureProxy*
|
|
TextureProxy::UseNextTextureProxyInLibrary()
|
|
{
|
|
Check_Object(this);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureProxy*
|
|
TextureProxy::UsePreviousTextureProxyInLibrary()
|
|
{
|
|
Check_Object(this);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
TextureProxy::GetName(MString *filename)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(filename);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
|
|
//
|
|
//------------------------
|
|
// Set the name and return
|
|
//------------------------
|
|
//
|
|
*filename = textureName;
|
|
return true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::SetName(const char* filename)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(filename);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
textureName = filename;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::GetImageSize(Vector2DOf<int> *size)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(size);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
*size = textureSize;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::GetChannelDepth(
|
|
unsigned *red_depth,
|
|
unsigned *blue_depth,
|
|
unsigned *green_depth,
|
|
unsigned *alpha_depth
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(red_depth);
|
|
Check_Pointer(blue_depth);
|
|
Check_Pointer(green_depth);
|
|
Check_Pointer(alpha_depth);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
|
|
//
|
|
//--------------------------------------------------------
|
|
// Get the texture attribute, and find out if we got alpha
|
|
//--------------------------------------------------------
|
|
//
|
|
*red_depth = redDepth;
|
|
*blue_depth = blueDepth;
|
|
*green_depth = greenDepth;
|
|
*alpha_depth = alphaDepth;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::GetChannels(
|
|
Stuff::DynamicArrayOf<BYTE> *red,
|
|
Stuff::DynamicArrayOf<BYTE> *green,
|
|
Stuff::DynamicArrayOf<BYTE> *blue,
|
|
Stuff::DynamicArrayOf<BYTE> *alpha
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(red);
|
|
Check_Object(green);
|
|
Check_Object(blue);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
|
|
//
|
|
//---------------------
|
|
// Now copy the channel
|
|
//---------------------
|
|
//
|
|
*red = redChannel;
|
|
*green = greenChannel;
|
|
*blue = blueChannel;
|
|
if (alpha)
|
|
{
|
|
Check_Object(alpha);
|
|
*alpha = alphaChannel;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::SetChannels(
|
|
const DynamicArrayOf<BYTE> *red,
|
|
const DynamicArrayOf<BYTE> *green,
|
|
const DynamicArrayOf<BYTE> *blue,
|
|
const DynamicArrayOf<BYTE> *alpha
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Verify(GetClassID() == TextureProxyClassID);
|
|
Check_Object(red);
|
|
Check_Object(green);
|
|
Check_Object(blue);
|
|
|
|
//
|
|
//---------------------
|
|
// Now copy the channel
|
|
//---------------------
|
|
//
|
|
Verify(red->GetLength() == textureSize.x*textureSize.y);
|
|
redChannel = *red;
|
|
redDepth = 8;
|
|
|
|
Verify(green->GetLength() == textureSize.x*textureSize.y);
|
|
greenChannel = *green;
|
|
greenDepth = 8;
|
|
|
|
Verify(blue->GetLength() == textureSize.x*textureSize.y);
|
|
blueChannel = *blue;
|
|
blueDepth = 8;
|
|
|
|
if (alpha)
|
|
{
|
|
Check_Object(alpha);
|
|
alphaChannel = *alpha;
|
|
alphaDepth = 8;
|
|
}
|
|
else
|
|
{
|
|
alphaChannel.SetLength(0);
|
|
alphaDepth = 0;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::SaveAsTarga(const char* filename)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(filename);
|
|
|
|
//
|
|
//---------------------------------------------
|
|
// Get the size of the image we will be copying
|
|
//---------------------------------------------
|
|
//
|
|
Vector2DOf<int> size;
|
|
GetImageSize(&size);
|
|
Verify(size.x > 0 && size.y > 0);
|
|
|
|
//
|
|
//----------------------------
|
|
// Analyze the type of texture
|
|
//----------------------------
|
|
//
|
|
unsigned
|
|
red_depth,
|
|
green_depth,
|
|
blue_depth,
|
|
alpha_depth;
|
|
GetChannelDepth(
|
|
&red_depth,
|
|
&green_depth,
|
|
&blue_depth,
|
|
&alpha_depth
|
|
);
|
|
Verify(red_depth == 8 && green_depth == 8 && blue_depth == 8);
|
|
Verify(!alpha_depth || alpha_depth == 8);
|
|
unsigned channel_size = size.x * size.y;
|
|
|
|
if (::gos_FileReadOnly(filename))
|
|
{
|
|
MString str;
|
|
str = MString(filename) + " is READ-ONLY. Remove the Read-Only permission and save?";
|
|
if (IDNO == MessageBox(NULL,str,"Save TGA",MB_YESNO))
|
|
{
|
|
return;
|
|
}
|
|
::gos_FileSetReadWrite(filename);
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// If this is an alpha texture, write out an alpha TGA after compositing
|
|
// the colors for it
|
|
//----------------------------------------------------------------------
|
|
//
|
|
DynamicArrayOf<BYTE> red;
|
|
DynamicArrayOf<BYTE> green;
|
|
DynamicArrayOf<BYTE> blue;
|
|
DynamicArrayOf<BYTE> alpha;
|
|
if (alpha_depth == 8)
|
|
{
|
|
GetChannels(&red, &green, &blue, &alpha);
|
|
Verify(red.GetLength() == channel_size);
|
|
Verify(green.GetLength() == channel_size);
|
|
Verify(blue.GetLength() == channel_size);
|
|
Verify(alpha.GetLength() == channel_size);
|
|
DynamicArrayOf<TargaColorA> buffer(channel_size);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
buffer[i].red = red[i];
|
|
buffer[i].green = green[i];
|
|
buffer[i].blue = blue[i];
|
|
buffer[i].alpha = alpha[i];
|
|
}
|
|
WriteTargaFile(
|
|
filename,
|
|
size.x,
|
|
size.y,
|
|
buffer
|
|
);
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// This is not an alpha texture, so just write out a regular TGA after
|
|
// compositing
|
|
//--------------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
GetChannels(&red, &green, &blue, NULL);
|
|
Verify(red.GetLength() == channel_size);
|
|
Verify(green.GetLength() == channel_size);
|
|
Verify(blue.GetLength() == channel_size);
|
|
DynamicArrayOf<TargaColor> buffer(channel_size);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
buffer[i].red = red[i];
|
|
buffer[i].green = green[i];
|
|
buffer[i].blue = blue[i];
|
|
}
|
|
WriteTargaFile(
|
|
filename,
|
|
size.x,
|
|
size.y,
|
|
buffer
|
|
);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::ReadTarga(
|
|
const char* filename,
|
|
unsigned *red_depth,
|
|
unsigned *blue_depth,
|
|
unsigned *green_depth,
|
|
unsigned *alpha_depth,
|
|
Vector2DOf<int> *size,
|
|
DynamicArrayOf<BYTE> *red,
|
|
DynamicArrayOf<BYTE> *green,
|
|
DynamicArrayOf<BYTE> *blue,
|
|
DynamicArrayOf<BYTE> *alpha
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(filename);
|
|
|
|
//
|
|
//--------------
|
|
// Open the file
|
|
//--------------
|
|
//
|
|
FileStream targa_file(filename);
|
|
if (!targa_file.IsFileOpened())
|
|
{
|
|
size->x = size->y = 0;
|
|
*red_depth = *green_depth = *blue_depth = *alpha_depth = 0;
|
|
return;
|
|
}
|
|
|
|
//
|
|
//----------------------
|
|
// Read the targa header
|
|
//----------------------
|
|
//
|
|
TargaHeader header;
|
|
ReadTargaHeader(
|
|
&header,
|
|
&targa_file,
|
|
&size->x,
|
|
&size->y,
|
|
red_depth,
|
|
green_depth,
|
|
blue_depth,
|
|
alpha_depth
|
|
);
|
|
Verify(size->x > 0 && size->y > 0);
|
|
Verify(*red_depth == 8 && *green_depth == 8 && *blue_depth == 8);
|
|
Verify(!*alpha_depth || *alpha_depth == 8);
|
|
|
|
//
|
|
//------------------------
|
|
// Set the channel lengths
|
|
//------------------------
|
|
//
|
|
unsigned channel_size = size->x * size->y;
|
|
red->SetLength(channel_size);
|
|
green->SetLength(channel_size);
|
|
blue->SetLength(channel_size);
|
|
|
|
//
|
|
//----------------------------------------------
|
|
// If this is an alpha texture, read it that way
|
|
//----------------------------------------------
|
|
//
|
|
if (*alpha_depth > 0)
|
|
{
|
|
alpha->SetLength(channel_size);
|
|
DynamicArrayOf<TargaColorA> raw(channel_size);
|
|
ReadTargaChannels(&targa_file, &header, &raw);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
(*red)[i] = raw[i].red;
|
|
(*green)[i] = raw[i].green;
|
|
(*blue)[i] = raw[i].blue;
|
|
(*alpha)[i] = raw[i].alpha;
|
|
}
|
|
}
|
|
|
|
//
|
|
//-----------------------------
|
|
// This is not an alpha texture
|
|
//-----------------------------
|
|
//
|
|
else
|
|
{
|
|
DynamicArrayOf<TargaColor> raw(channel_size);
|
|
ReadTargaChannels(&targa_file, &header, &raw);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
(*red)[i] = raw[i].red;
|
|
(*green)[i] = raw[i].green;
|
|
(*blue)[i] = raw[i].blue;
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::ReadPNG(
|
|
const char* filename,
|
|
unsigned *red_depth,
|
|
unsigned *blue_depth,
|
|
unsigned *green_depth,
|
|
unsigned *alpha_depth,
|
|
Vector2DOf<int> *size,
|
|
DynamicArrayOf<BYTE> *red,
|
|
DynamicArrayOf<BYTE> *green,
|
|
DynamicArrayOf<BYTE> *blue,
|
|
DynamicArrayOf<BYTE> *alpha
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(filename);
|
|
|
|
//
|
|
//--------------
|
|
// Open the file
|
|
//--------------
|
|
//
|
|
if (!::gos_DoesFileExist(filename))
|
|
{
|
|
size->x = size->y = 0;
|
|
*red_depth = *green_depth = *blue_depth = *alpha_depth = 0;
|
|
return;
|
|
}
|
|
|
|
Image image;
|
|
image.Load((char *)filename);
|
|
|
|
size->x = image.GetWidth();
|
|
size->y = image.GetHeight();
|
|
*red_depth = 8;
|
|
*green_depth = 8;
|
|
*blue_depth = 8;
|
|
|
|
/* default mask in Image::CreateBlank has red in the most significant byte */
|
|
/* so make sure here the right mask is set */
|
|
RGBMask mask;
|
|
if(image.GetBpp()==32)
|
|
{
|
|
mask.Set(0x0000ff,0x00ff00,0xff0000);
|
|
*alpha_depth = 8;
|
|
}
|
|
else {
|
|
mask.Set(0x000000ff,0x0000ff00,0x00ff0000,0xff000000);
|
|
*alpha_depth = 0;
|
|
}
|
|
|
|
image.MaskTo(mask);
|
|
|
|
Verify(size->x > 0 && size->y > 0);
|
|
Verify(*red_depth == 8 && *green_depth == 8 && *blue_depth == 8);
|
|
Verify(!*alpha_depth || *alpha_depth == 8);
|
|
|
|
//
|
|
//------------------------
|
|
// Set the channel lengths
|
|
//------------------------
|
|
//
|
|
unsigned channel_size = size->x * size->y;
|
|
red->SetLength(channel_size);
|
|
green->SetLength(channel_size);
|
|
blue->SetLength(channel_size);
|
|
|
|
//
|
|
//----------------------------------------------
|
|
// If this is an alpha texture, read it that way
|
|
//----------------------------------------------
|
|
//
|
|
BYTE *dat = (BYTE *)image.Lock();
|
|
if (*alpha_depth > 0)
|
|
{
|
|
alpha->SetLength(channel_size);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
(*red)[i] = *(dat+i*4+0);
|
|
(*green)[i] = *(dat+i*4+1);
|
|
(*blue)[i] = *(dat+i*4+2);
|
|
(*alpha)[i] = *(dat+i*4+3);
|
|
}
|
|
}
|
|
|
|
//
|
|
//-----------------------------
|
|
// This is not an alpha texture
|
|
//-----------------------------
|
|
//
|
|
else
|
|
{
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
(*red)[i] = *(dat+i*3+0);
|
|
(*green)[i] = *(dat+i*3+1);
|
|
(*blue)[i] = *(dat+i*3+2);
|
|
}
|
|
}
|
|
image.UnLock();
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
/* function name: SaveAsPng
|
|
/* description:
|
|
/*******************************************************************************/
|
|
void TextureProxy::SaveAsPng(const char* filename)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(filename);
|
|
|
|
//
|
|
//---------------------------------------------
|
|
// Get the size of the image we will be copying
|
|
//---------------------------------------------
|
|
//
|
|
Vector2DOf<int> size;
|
|
GetImageSize(&size);
|
|
Verify(size.x > 0 && size.y > 0);
|
|
|
|
//
|
|
//----------------------------
|
|
// Analyze the type of texture
|
|
//----------------------------
|
|
//
|
|
unsigned
|
|
red_depth,
|
|
green_depth,
|
|
blue_depth,
|
|
alpha_depth;
|
|
GetChannelDepth(
|
|
&red_depth,
|
|
&green_depth,
|
|
&blue_depth,
|
|
&alpha_depth
|
|
);
|
|
Verify(red_depth == 8 && green_depth == 8 && blue_depth == 8);
|
|
Verify(!alpha_depth || alpha_depth == 8);
|
|
unsigned channel_size = size.x * size.y;
|
|
|
|
/* default mask in Image::CreateBlank has red in the most significant byte */
|
|
/* so make sure here the right mask is set */
|
|
RGBMask mask;
|
|
if(alpha_depth==0)
|
|
mask.Set(0x0000ff,0x00ff00,0xff0000);
|
|
else
|
|
mask.Set(0x000000ff,0x0000ff00,0x00ff0000,0xff000000);
|
|
|
|
Image pngImage;
|
|
pngImage.CreateBlank(size.x, size.y, ITYPE_RGB, alpha_depth?32:24, mask);
|
|
|
|
BYTE *dat=(BYTE *)pngImage.Lock();
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// If this is an alpha texture, write out RGBA
|
|
//----------------------------------------------------------------------
|
|
//
|
|
DynamicArrayOf<BYTE> red;
|
|
DynamicArrayOf<BYTE> green;
|
|
DynamicArrayOf<BYTE> blue;
|
|
DynamicArrayOf<BYTE> alpha;
|
|
if (alpha_depth == 8)
|
|
{
|
|
GetChannels(&red, &green, &blue, &alpha);
|
|
Verify(red.GetLength() == channel_size);
|
|
Verify(green.GetLength() == channel_size);
|
|
Verify(blue.GetLength() == channel_size);
|
|
Verify(alpha.GetLength() == channel_size);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
*(dat+i*4+0) = red[i];
|
|
*(dat+i*4+1) = green[i];
|
|
*(dat+i*4+2) = blue[i];
|
|
*(dat+i*4+3) = alpha[i];
|
|
}
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// This is not an alpha texture, so just write out RGB
|
|
//--------------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
GetChannels(&red, &green, &blue, NULL);
|
|
Verify(red.GetLength() == channel_size);
|
|
Verify(green.GetLength() == channel_size);
|
|
Verify(blue.GetLength() == channel_size);
|
|
for (int i=0; i<channel_size; ++i)
|
|
{
|
|
*(dat+i*3+0) = red[i];
|
|
*(dat+i*3+1) = green[i];
|
|
*(dat+i*3+2) = blue[i];
|
|
}
|
|
}
|
|
|
|
pngImage.UnLock();
|
|
if (::gos_FileReadOnly(filename))
|
|
{
|
|
MString str;
|
|
str = MString(filename) + " is READ-ONLY. Remove the Read-Only permission and save?";
|
|
if (IDNO == MessageBox(NULL,str,"Save PNG",MB_YESNO))
|
|
{
|
|
return;
|
|
}
|
|
::gos_FileSetReadWrite(filename);
|
|
}
|
|
pngImage.SavePng((char* )filename);
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool TextureProxy:: GetFormat(Proxies::TextureProxy::FormatType* format)
|
|
{
|
|
Check_Object(this);
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void TextureProxy:: SetFormat(Proxies::TextureProxy::FormatType format)
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureProxy::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//
|
|
//############################################################################
|
|
//###################### TextureLibrary ##########################
|
|
//############################################################################
|
|
//
|
|
|
|
TextureLibrary::ClassData*
|
|
TextureLibrary::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureLibrary::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
TextureLibraryClassID,
|
|
"TextureLibrary",
|
|
GenericProxy::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureLibrary::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureLibrary::TextureLibrary(
|
|
ClassData *class_data,
|
|
StateLibrary *state_library
|
|
):
|
|
GenericProxy(class_data),
|
|
stateLibrary(state_library),
|
|
activeTextureProxies(NULL)
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TextureLibrary::~TextureLibrary()
|
|
{
|
|
Check_Object(this);
|
|
Verify(activeTextureProxies.IsEmpty());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
TextureLibrary::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|