BOOL CSceneConverter::ConvertTexture(CGraphicsTexture** ppcGraphicsTexture, D3DFORMAT d3dFormat, CImage* pcImage, BOOL bDiscard, int iWidth, int iHeight, EPrimitiveTypes eType, EChannel eFirst, ...)
{
	va_list				vaMarker;
	int					iCount;
	EChannel		eIC;
	CImage				cExport;
	BOOL				bResult;

	cExport.Init();
	iCount = 0;
	eIC = eFirst;

	cExport.BeginChange();
	va_start(vaMarker, eFirst);
	while (eIC != CHANNEL_ZERO)
	{
		cExport.AddChannel(eIC, eType);
		iCount++;
		eIC = va_arg(vaMarker, EChannel);
	}
	va_end(vaMarker);

	cExport.SetSize(iWidth, iHeight);
	cExport.SetData((void*)1);
	cExport.EndChange();

	bResult = mcTextureConverter.Convert(ppcGraphicsTexture, d3dFormat, pcImage, &cExport, bDiscard);
	cExport.Kill();
	return bResult;
}
void TestImageColourMultiAccessor(void)
{
	CImageColourNormal		cNormal;
	CImageColourOpacity		cAlpha;
	CImageColourCombo2		cColour;
	CChannels*				pcChannels;
	CImageAccessor*			pcAccessor;
	CImage					cImage;
	SImageColour			sDest;
	BOOL					bResult;

	cNormal.Init(0.7f, -0.6f, -0.5f);
	cAlpha.Init(0.333f);
	cColour.Init(&cNormal, &cAlpha);

	cImage.Init();
	cImage.BeginChange();
	cImage.AddChannel(IMAGE_DIFFUSE_GREEN, PT_uchar);
	cImage.AddChannel(IMAGE_NORMAL_Y, PT_float);
	cImage.AddChannel(IMAGE_DIFFUSE_BLUE, PT_uchar);
	cImage.AddChannel(IMAGE_OPACITY, PT_ushort);
	cImage.AddChannel(IMAGE_DIFFUSE_RED, PT_uchar);
	cImage.AddChannel(IMAGE_MASK, PT_int);
	cImage.AddChannel(IMAGE_NORMAL_Z, PT_float);
	cImage.AddChannel(IMAGE_NORMAL_X, PT_float);
	cImage.SetSize(1, 2);
	cImage.EndChange();
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, IMAGE_NORMAL_X, IMAGE_NORMAL_Y, IMAGE_NORMAL_Z, IMAGE_OPACITY, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cColour);
	AssertBool(TRUE, bResult);

	AssertFloat(0.7f, *((float*)&((sDest).c)[0x0]), 3);
	AssertFloat(-0.6f, *((float*)&((sDest).c)[0x4]), 3);
	AssertFloat(-0.5f, *((float*)&((sDest).c)[0x8]), 3);
	AssertShortHex(0x553f, *((unsigned short*)&((sDest).c)[0xc]));

	pcAccessor->Set(0, 1, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;
	AssertFloat(-0.6f, *(float*)&(pcChannels->GetData()[22]), 3);
	AssertFloat( 0.7f, *(float*)&(pcChannels->GetData()[38]), 3);
	AssertFloat(-0.5f, *(float*)&(pcChannels->GetData()[34]), 3);
	AssertShortHex(0x553f, *(unsigned short*)&(pcChannels->GetData()[27]));
}
void TestImageColourAccessorFloats(void)
{
	CImageColourNormal	cNormal;
	CChannels*			pcChannels;
	CImageAccessor*		pcAccessor;
	CImage				cImage;
	SImageColour		sDest;
	BOOL				bResult;

	cNormal.Init(0.7f, 0.6f, 0.5f);
	cImage.Init();
	cImage.BeginChange();
	cImage.AddChannel(IMAGE_DIFFUSE_GREEN, PT_uchar);
	cImage.AddChannel(IMAGE_NORMAL_Y, PT_float);
	cImage.AddChannel(IMAGE_DIFFUSE_BLUE, PT_uchar);
	cImage.AddChannel(IMAGE_OPACITY, PT_short);
	cImage.AddChannel(IMAGE_DIFFUSE_RED, PT_uchar);
	cImage.AddChannel(IMAGE_MASK, PT_int);
	cImage.AddChannel(IMAGE_NORMAL_Z, PT_float);
	cImage.AddChannel(IMAGE_NORMAL_X, PT_float);
	cImage.SetSize(1, 2);
	cImage.EndChange();
	cImage.Clear();

	pcAccessor = CImageAccessorCreator::Create(&cImage, PT_float, IMAGE_NORMAL_X, IMAGE_NORMAL_Y, IMAGE_NORMAL_Z, CHANNEL_ZERO);

	sDest.Full();
	bResult = pcAccessor->MakeColour(&sDest, &cNormal);
	AssertBool(TRUE, bResult);

	AssertFloat(0.7f, *((float*)&((sDest).c)[0x0]), 3);
	AssertFloat(0.6f, *((float*)&((sDest).c)[0x4]), 3);
	AssertFloat(0.5f, *((float*)&((sDest).c)[0x8]), 3);

	pcAccessor->Set(0, 1, &sDest);
	pcAccessor->Kill();

	pcChannels = &cImage.mcChannels;
	
	AssertFloat(0.6f, *(float*)&(pcChannels->GetData()[22]), 3);
	AssertFloat(0.7f, *(float*)&(pcChannels->GetData()[38]), 3);
	AssertFloat(0.5f, *(float*)&(pcChannels->GetData()[34]), 3);
}
BOOL LoadUncompressedTrueColourTGA(CImage *pcImage, char *szFilename)
{
	STGAImageHeader 		sTGAImageHeader;
	STGAFileHeader  		sTGAFileHeader;				// Used To Store Our File Header
	CFileBasic				sFile;
	int   					iWidth;
	int   					iHeight;
	int   					iBitsPerPixel;
	int   					iBytesPerPixel;
	int   					iImageSize;
	unsigned char*			pvMem;
	CImage					cImageImport;
	CImageCopier			cCopier;
	filePos					iRead;
	int						i;
	int						iStride;

	//----------------------------------------------------------------------
	// open the tga file.
	//----------------------------------------------------------------------
	sFile.Init(DiskFile(szFilename));
	if (!sFile.Open(EFM_Read))
	{
		sFile.Kill();
		return FALSE;
	}

	//----------------------------------------------------------------------
	// read the header
	//----------------------------------------------------------------------

	//Error check please.
	memset(&sTGAFileHeader, 0, sizeof(STGAFileHeader));
	sFile.Read(&sTGAFileHeader.iIDLength, 1, 1);
	sFile.Read(&sTGAFileHeader.iColourMapType, 1, 1);
	sFile.Read(&sTGAFileHeader.iImageType, 1, 1);
	sFile.Read(&sTGAFileHeader.iFirstEntryIndex, 2, 1);
	sFile.Read(&sTGAFileHeader.iColourMapLength, 2, 1);
	sFile.Read(&sTGAFileHeader.iColourMapEntrySize, 1, 1);
	sFile.Read(&sTGAFileHeader.iOriginX, 2, 1);
	sFile.Read(&sTGAFileHeader.iOriginY, 2, 1);

	//Error check please.
	memset(&sTGAImageHeader, 0, sizeof(STGAImageHeader));
	sFile.Read(&sTGAImageHeader.iImageWidth, 2, 1);
	sFile.Read(&sTGAImageHeader.iImageHeight, 2, 1);
	sFile.Read(&sTGAImageHeader.iPixelDepth, 1, 1);
	sFile.Read(&sTGAImageHeader.iPixelDescriptor, 1, 1);


	//----------------------------------------------------------------------
	// get the TGA dimensions
	//----------------------------------------------------------------------
	iWidth        = (sTGAImageHeader.iImageWidth);
	iHeight       = (sTGAImageHeader.iImageHeight);
	iBitsPerPixel = sTGAImageHeader.iPixelDepth;

	//----------------------------------------------------------------------
	// Make Sure All Information Is Valid
	//----------------------------------------------------------------------
	if ((iWidth <= 0) || (iHeight <= 0))
	{
		sFile.Close();
		sFile.Kill();
		return FALSE;
	}

	switch (iBitsPerPixel)
	{
	case 16:
		iBytesPerPixel = 2;
		break;
	case 24:
		iBytesPerPixel = 3;
		break;
	case 32:
		iBytesPerPixel = 4;
		break;
	default:
		sFile.Close();
		sFile.Kill();
		return FALSE;
	}

	iBytesPerPixel = (iBitsPerPixel / 8);				  // Calculate The BYTES Per Pixel
	iImageSize     = (iBytesPerPixel * iWidth * iHeight); // Calculate Memory Needed To Store Image
	iStride = iWidth * iBytesPerPixel;

	pvMem = (unsigned char*)malloc(iImageSize);
	iRead = sFile.Read(pvMem, iImageSize, 1);
	if (iRead != 1)
	{
		free(pvMem);
		sFile.Close();
		sFile.Kill();
		return FALSE;	
	}
	sFile.Close();
	sFile.Kill();


	cImageImport.Init();
	cImageImport.BeginChange();
	pcImage->Init();
	pcImage->BeginChange();
	if (iBytesPerPixel == 3)
	{
		cImageImport.AddChannel(IMAGE_DIFFUSE_BLUE, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_RED, PT_uchar);
		pcImage->AddChannel(IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, PT_uchar);
	}
	else if (iBytesPerPixel == 4)
	{
		cImageImport.AddChannel(IMAGE_DIFFUSE_BLUE, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_RED, IMAGE_OPACITY, PT_uchar);
		pcImage->AddChannel(IMAGE_OPACITY, IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, PT_uchar);
	}
	else if (iBytesPerPixel == 2)
	{
		cImageImport.AddChannel(IMAGE_DIFFUSE_BLUE, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_RED, PT_nickle);
		cImageImport.AddChannel(IMAGE_IGNORED, PT_bit);
		pcImage->AddChannel(IMAGE_DIFFUSE_RED, IMAGE_DIFFUSE_GREEN, IMAGE_DIFFUSE_BLUE, PT_uchar);
	}
	cImageImport.SetSize(iWidth, iHeight);
	pcImage->SetSize(iWidth, iHeight);
	pcImage->EndChange();
	cImageImport.SetData(pvMem);
	cImageImport.EndChange();

	cCopier.Init(&cImageImport, pcImage);
	for (i = 0; i < iHeight; i++)
	{
		cImageImport.SetData(&pvMem[iStride* ((iHeight-1) - i)]);
		cCopier.Copy(0, i, 0, 0, iWidth, 1);
	}
	cCopier.Kill();
	cImageImport.Kill();

	free(pvMem);
	return TRUE;
}