462 lines
15 KiB
C++
462 lines
15 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) Microsoft Corporation, 2000.
|
|
//
|
|
// refrast.cpp
|
|
//
|
|
// Direct3D Reference Device - rasterizer miscellaneous
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "pch.cpp"
|
|
#pragma hdrstop
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// RDColor //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
RDColor::ConvertFrom( RDSurfaceFormat Type, const char* pSurfaceBits )
|
|
{
|
|
UINT16 u16BITS;
|
|
UINT8 u8BITS;
|
|
|
|
switch (Type)
|
|
{
|
|
default:
|
|
case RD_SF_NULL: return;
|
|
case RD_SF_B8G8R8A8: *this = *((UINT32*)pSurfaceBits); break;
|
|
case RD_SF_B8G8R8X8: *this = *((UINT32*)pSurfaceBits); A = 1.F; break;
|
|
|
|
case RD_SF_B5G6R5:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = ((u16BITS>>(6+5)) & 0x001F)/31.f;
|
|
G = ((u16BITS>> 5) & 0x003F)/63.f;
|
|
B = ((u16BITS ) & 0x001F)/31.f;
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RD_SF_B5G5R5X1:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = ((u16BITS>>(5+5)) & 0x001F)/31.f;
|
|
G = ((u16BITS>> 5) & 0x001F)/31.f;
|
|
B = ((u16BITS ) & 0x001F)/31.f;
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RD_SF_B5G5R5A1:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = ((u16BITS>>(5+5)) & 0x001F)/31.f;
|
|
G = ((u16BITS>> 5) & 0x001F)/31.f;
|
|
B = ((u16BITS ) & 0x001F)/31.f;
|
|
A = ( u16BITS & 0x8000 ) ? 1.f : 0.f;
|
|
break;
|
|
|
|
case RD_SF_B4G4R4A4:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = ((u16BITS>> (4+4)) & 0x000F)/15.f;
|
|
G = ((u16BITS>> (4)) & 0x000F)/15.f;
|
|
B = ((u16BITS ) & 0x000F)/15.f;
|
|
A = ((u16BITS>>(4+4+4)) & 0x000F)/15.f;
|
|
break;
|
|
|
|
case RD_SF_B4G4R4X4:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = ((u16BITS>>(4+4)) & 0x000F)/15.f;
|
|
G = ((u16BITS>> (4)) & 0x000F)/15.f;
|
|
B = ((u16BITS ) & 0x000F)/15.f;
|
|
A = 1.f;
|
|
break;
|
|
|
|
case RD_SF_B8G8R8:
|
|
R = *((UINT8*)pSurfaceBits+2)/255.f;
|
|
G = *((UINT8*)pSurfaceBits+1)/255.f;
|
|
B = *((UINT8*)pSurfaceBits+0)/255.f;
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RD_SF_L8:
|
|
R = G = B = *((UINT8*)pSurfaceBits)/255.f;
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RD_SF_L8A8:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = G = B = (UINT8)(0xff & u16BITS)/255.f;
|
|
A = (UINT8)(0xff & (u16BITS >> 8))/255.f;
|
|
break;
|
|
|
|
case RD_SF_A8:
|
|
R = G = B = 0.f;
|
|
A = *((UINT8*)pSurfaceBits)/255.f;
|
|
break;
|
|
|
|
case RD_SF_B2G3R3:
|
|
u8BITS = *((UINT8*)pSurfaceBits);
|
|
R = ((u8BITS>>(3+2)) & 0x07)/7.f;
|
|
G = ((u8BITS>> 2) & 0x07)/7.f;
|
|
B = ((u8BITS ) & 0x03)/3.f;
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RD_SF_L4A4:
|
|
u16BITS = *((UINT8*)pSurfaceBits);
|
|
R = G = B = (u16BITS & 0x0f)/15.f;
|
|
A = ((u16BITS>>4) & 0x0f)/15.f;
|
|
break;
|
|
|
|
case RD_SF_B2G3R3A8:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = ((u16BITS>>(3+2)) & 0x07)/7.f;
|
|
G = ((u16BITS>> 2) & 0x07)/7.f;
|
|
B = ((u16BITS ) & 0x03)/3.f;
|
|
A = (UINT8)(0xff & (u16BITS >> 8))/255.f;
|
|
break;
|
|
|
|
case RD_SF_U8V8:
|
|
{
|
|
INT8 iDU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iDV = *(( INT8*)pSurfaceBits+1);
|
|
R = CLAMP_SIGNED8(iDU); // fDU
|
|
G = CLAMP_SIGNED8(iDV); // fDV
|
|
B = 1.0F; // fL
|
|
A = 1.F;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_U16V16:
|
|
{
|
|
INT16 iDU = *(( INT16*)pSurfaceBits+0);
|
|
INT16 iDV = *(( INT16*)pSurfaceBits+1);
|
|
R = CLAMP_SIGNED16(iDU); // fDU
|
|
G = CLAMP_SIGNED16(iDV); // fDV
|
|
B = 1.0f; // 1.0 here is intentional
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_U5V5L6:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
INT8 iDU = (INT8)(u16BITS & 0x1f);
|
|
INT8 iDV = (INT8)((u16BITS>>5) & 0x1f);
|
|
UINT8 uL = (UINT8)(u16BITS >> 10);
|
|
R = CLAMP_SIGNED5(iDU); // fDU
|
|
G = CLAMP_SIGNED5(iDV); // fDV
|
|
// the unsigned uL is normalized with 2^N - 1, since this is the
|
|
// largest representable value
|
|
B = (FLOAT)uL * (1.0F/63.0F); // fL
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_U8V8L8X8:
|
|
{
|
|
INT8 iDU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iDV = *(( INT8*)pSurfaceBits+1);
|
|
UINT8 uL = *((UINT8*)pSurfaceBits+2);
|
|
R = CLAMP_SIGNED8(iDU); // fDU
|
|
G = CLAMP_SIGNED8(iDV); // fDV
|
|
// the unsigned uL is normalized with 2^N - 1, since this is the
|
|
// largest representable value
|
|
B = (FLOAT)uL * (1.0F/255.0F); // fL
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
case RD_SF_U8V8W8Q8:
|
|
{
|
|
INT8 iDU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iDV = *(( INT8*)pSurfaceBits+1);
|
|
INT8 iDW = *(( INT8*)pSurfaceBits+2);
|
|
INT8 iDQ = *(( INT8*)pSurfaceBits+3);
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = CLAMP_SIGNED8(iDU); // fDU
|
|
G = CLAMP_SIGNED8(iDV); // fDV
|
|
B = CLAMP_SIGNED8(iDW); // fDW
|
|
A = CLAMP_SIGNED8(iDQ); // fDQ
|
|
}
|
|
break;
|
|
case RD_SF_U10V11W11:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
INT16 iDU = (INT16)((u32BITS>>(0 )) & 0x3FF);
|
|
INT16 iDV = (INT16)((u32BITS>>(10 )) & 0x7FF);
|
|
INT16 iDW = (INT16)((u32BITS>>(10+11)) & 0x7FF);
|
|
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = CLAMP_SIGNED10(iDU); // fDU
|
|
G = CLAMP_SIGNED11(iDV); // fDV
|
|
B = CLAMP_SIGNED11(iDW); // fDW
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
case RD_SF_R10G10B10A2:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = ((u32BITS>>(0 )) & 0x3FF)/1023.f;
|
|
G = ((u32BITS>>(10 )) & 0x3FF)/1023.f;
|
|
B = ((u32BITS>>(10+10)) & 0x3FF)/1023.f;
|
|
A = ((u32BITS>>(10+10+10)) & 0x3)/3.f;
|
|
}
|
|
break;
|
|
case RD_SF_R8G8B8A8:
|
|
{
|
|
R = *(( UINT8*)pSurfaceBits+0)/255.f;
|
|
G = *(( UINT8*)pSurfaceBits+1)/255.f;
|
|
B = *(( UINT8*)pSurfaceBits+2)/255.f;
|
|
A = *(( UINT8*)pSurfaceBits+3)/255.f;
|
|
}
|
|
break;
|
|
case RD_SF_R8G8B8X8:
|
|
{
|
|
R = *(( UINT8*)pSurfaceBits+0)/255.f;
|
|
G = *(( UINT8*)pSurfaceBits+1)/255.f;
|
|
B = *(( UINT8*)pSurfaceBits+2)/255.f;
|
|
A = 1.f;
|
|
}
|
|
break;
|
|
case RD_SF_R16G16:
|
|
{
|
|
R = *(( UINT16*)pSurfaceBits+0)/65535.f;
|
|
G = *(( UINT16*)pSurfaceBits+1)/65535.f;
|
|
B = 1.0f; // 1.0 here is intentional
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
case RD_SF_U11V11W10:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
INT16 iDU = (INT16)((u32BITS>>(0 )) & 0x7FF);
|
|
INT16 iDV = (INT16)((u32BITS>>(11 )) & 0x7FF);
|
|
INT16 iDW = (INT16)((u32BITS>>(11+11)) & 0x3FF);
|
|
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = CLAMP_SIGNED11(iDU); // fDU
|
|
G = CLAMP_SIGNED11(iDV); // fDV
|
|
B = CLAMP_SIGNED10(iDW); // fDW
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
case RD_SF_U10V10W10A2:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
INT16 iDU = (INT16)((u32BITS>>(0 )) & 0x3FF);
|
|
INT16 iDV = (INT16)((u32BITS>>(10 )) & 0x3FF);
|
|
INT16 iDW = (INT16)((u32BITS>>(10+10)) & 0x3FF);
|
|
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = CLAMP_SIGNED10(iDU); // fDU
|
|
G = CLAMP_SIGNED10(iDV); // fDV
|
|
B = CLAMP_SIGNED10(iDW); // fDW
|
|
|
|
// Note: The A component is treated as an unsigned component
|
|
A = ((u32BITS>>(10+10+10)) & 0x3)/3.f;
|
|
}
|
|
break;
|
|
case RD_SF_U8V8X8A8:
|
|
{
|
|
INT8 iU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iV = *(( INT8*)pSurfaceBits+1);
|
|
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = CLAMP_SIGNED8(iU);
|
|
G = CLAMP_SIGNED8(iV);
|
|
B = 1.0f;
|
|
|
|
// Note: The A component is treated as unsigned
|
|
A = *(( INT8*)pSurfaceBits+3)/255.f;
|
|
}
|
|
break;
|
|
case RD_SF_U8V8X8L8:
|
|
{
|
|
INT8 iU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iV = *(( INT8*)pSurfaceBits+1);
|
|
INT8 iL = *(( INT8*)pSurfaceBits+3);
|
|
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = CLAMP_SIGNED8(iU);
|
|
G = CLAMP_SIGNED8(iV);
|
|
B = CLAMP_SIGNED8(iL);
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
// shadow map texture formats (read only, not needed for ConvertTo)
|
|
case RD_SF_Z16S0:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)u16BITS * (1.0F/(FLOAT)0xffff);
|
|
B = 0.0F;
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_Z24S8:
|
|
case RD_SF_Z24X8:
|
|
case RD_SF_Z24X4S4:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u32BITS>>8) * (1.0F/(FLOAT)0xffffff);
|
|
B = 0.0F;
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_S8Z24:
|
|
case RD_SF_X8Z24:
|
|
case RD_SF_X4S4Z24:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u32BITS&0x00ffffff) * (1.0F/(FLOAT)0xffffff);
|
|
B = 0.0F;
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_Z15S1:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u16BITS>>1) * (1.0F/(FLOAT)0x7fff);
|
|
B = 0.0F;
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_S1Z15:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u16BITS&0x7fff) * (1.0F/(FLOAT)0x7fff);
|
|
B = 0.0F;
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
|
|
case RD_SF_Z32S0:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)u32BITS * (1.0F/(FLOAT)0xffffffff);
|
|
B = 0.0F;
|
|
A = 1.0f;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Convert surface type format to RDColor
|
|
void
|
|
RDColor::ConvertTo( RDSurfaceFormat Type, float fRoundOffset, char* pSurfaceBits ) const
|
|
{
|
|
int iR, iG, iB, iA;
|
|
|
|
switch (Type)
|
|
{
|
|
case RD_SF_B8G8R8A8:
|
|
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+3) = (UINT8)((FLOAT)A * 255. + fRoundOffset);
|
|
break;
|
|
|
|
case RD_SF_B8G8R8X8:
|
|
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+3) = 0x00;
|
|
break;
|
|
|
|
case RD_SF_B8G8R8:
|
|
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
|
|
break;
|
|
|
|
case RD_SF_B4G4R4A4:
|
|
iA = (FLOAT)A * 15. + fRoundOffset;
|
|
iR = (FLOAT)R * 15. + fRoundOffset;
|
|
iG = (FLOAT)G * 15. + fRoundOffset;
|
|
iB = (FLOAT)B * 15. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (iA<<12) | (iR<<8) | (iG<<4) | iB;
|
|
break;
|
|
|
|
case RD_SF_B4G4R4X4:
|
|
iR = (FLOAT)R * 15. + fRoundOffset;
|
|
iG = (FLOAT)G * 15. + fRoundOffset;
|
|
iB = (FLOAT)B * 15. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (0x00<<12) | (iR<<8) | (iG<<4) | iB;
|
|
break;
|
|
|
|
case RD_SF_B5G6R5:
|
|
iR = (FLOAT)R * 31. + fRoundOffset; // apply rounding bias then truncate
|
|
iG = (FLOAT)G * 63. + fRoundOffset;
|
|
iB = (FLOAT)B * 31. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (iR<<11) | (iG<<5) | iB;
|
|
break;
|
|
|
|
case RD_SF_B5G5R5A1:
|
|
iA = (FLOAT)A * 1. + fRoundOffset;
|
|
iR = (FLOAT)R * 31. + fRoundOffset;
|
|
iG = (FLOAT)G * 31. + fRoundOffset;
|
|
iB = (FLOAT)B * 31. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (iA<<15) | (iR<<10) | (iG<<5) | iB;
|
|
break;
|
|
|
|
case RD_SF_B5G5R5X1:
|
|
iR = (FLOAT)R * 31. + fRoundOffset;
|
|
iG = (FLOAT)G * 31. + fRoundOffset;
|
|
iB = (FLOAT)B * 31. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (iR<<10) | (iG<<5) | iB;
|
|
break;
|
|
|
|
case RD_SF_B2G3R3:
|
|
iR = (FLOAT)R * 7. + fRoundOffset;
|
|
iG = (FLOAT)G * 7. + fRoundOffset;
|
|
iB = (FLOAT)B * 3. + fRoundOffset;
|
|
*((UINT8*)pSurfaceBits) = (iR<<5) | (iG<<2) | iB;
|
|
break;
|
|
|
|
case RD_SF_B2G3R3A8:
|
|
iA = (FLOAT)A * 255. + fRoundOffset;
|
|
iR = (FLOAT)R * 7. + fRoundOffset;
|
|
iG = (FLOAT)G * 7. + fRoundOffset;
|
|
iB = (FLOAT)B * 3. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (iA<<8) | (iR<<5) | (iG<<2) | iB;
|
|
break;
|
|
|
|
case RD_SF_R10G10B10A2:
|
|
iR = (FLOAT)R * 1023.f + fRoundOffset;
|
|
iG = (FLOAT)G * 1023.f + fRoundOffset;
|
|
iB = (FLOAT)B * 1023.f + fRoundOffset;
|
|
iA = (FLOAT)A * 3.f + fRoundOffset;
|
|
*((UINT32*)pSurfaceBits) = (iA<<(10+10+10)) | (iB<<(10+10)) | (iG<<10) | iR;
|
|
break;
|
|
|
|
case RD_SF_R8G8B8A8:
|
|
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+3) = (UINT8)((FLOAT)A * 255. + fRoundOffset);
|
|
break;
|
|
|
|
case RD_SF_R8G8B8X8:
|
|
*((UINT8*)pSurfaceBits+0) = (UINT8)((FLOAT)R * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+1) = (UINT8)((FLOAT)G * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+2) = (UINT8)((FLOAT)B * 255. + fRoundOffset);
|
|
*((UINT8*)pSurfaceBits+3) = 0x00;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// end
|