You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
773 lines
27 KiB
773 lines
27 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) Microsoft Corporation, 1998.
|
|
//
|
|
// refrasti.hpp
|
|
//
|
|
// Direct3D Reference Rasterizer - Main Internal Header File
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef _REFRASTI_HPP
|
|
#define _REFRASTI_HPP
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Pixel Component Classes //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Color Component Class - Class used for color channel (alpha & rgb)
|
|
// processing.
|
|
//
|
|
// Internal format is single precision floating point. The 1.0 value maps
|
|
// to 0xff for 8 bit color.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class RRColorComp
|
|
{
|
|
FLOAT m_fVal;
|
|
|
|
public:
|
|
|
|
// default, UINT8, & FLOAT assignment constructor
|
|
RRColorComp(void) : m_fVal(0.F) {;}
|
|
RRColorComp(UINT8 uVal) : m_fVal((FLOAT)uVal/255.F) {;}
|
|
RRColorComp(FLOAT fVal) : m_fVal(fVal) {;}
|
|
|
|
// copy and assignment operators
|
|
RRColorComp& operator=(const RRColorComp& A) { m_fVal = A.m_fVal; return *this; }
|
|
RRColorComp& operator=(UINT8 uVal) { m_fVal = (1.f/255.f)*(FLOAT)uVal; return *this; }
|
|
RRColorComp& operator=(FLOAT fVal) { m_fVal = fVal; return *this; }
|
|
// round for integer get operations
|
|
operator UINT8() const { return (UINT8)( ( (255.f)*m_fVal) + .5f); }
|
|
operator unsigned() const { return (unsigned)( ( (255.f)*m_fVal ) + .5f); }
|
|
operator FLOAT() const { return m_fVal; }
|
|
|
|
// fixed point get function - specify number of integral and fractional bits
|
|
INT32 GetFixed( int iIntBits, int iFracBits ) const
|
|
{
|
|
// float value is in 0. to 1. range, so scale up by the total number of
|
|
// bits (the '-1' does the mapping such that (2**n)-1 is the max representable
|
|
// value, for example 0xff is max for 8 integral bits (not 0x100))
|
|
return (INT32)( ( m_fVal * (FLOAT)((1<<(iIntBits+iFracBits))-1) ) + .5f);
|
|
}
|
|
|
|
//
|
|
// overloaded arithmetic operators - not much going on here for floating
|
|
// point (would be much more interesting if internal representation was
|
|
// fixed point)
|
|
//
|
|
|
|
// use compliment operator for component inverse (1. - value)
|
|
friend RRColorComp operator~(const RRColorComp& A)
|
|
{
|
|
return RRColorComp( 1.F - A.m_fVal );
|
|
}
|
|
|
|
friend RRColorComp operator+(const RRColorComp& A, const RRColorComp& B)
|
|
{
|
|
return RRColorComp( A.m_fVal + B.m_fVal );
|
|
}
|
|
RRColorComp& operator+=(const RRColorComp& A)
|
|
{
|
|
m_fVal += A.m_fVal; return *this;
|
|
}
|
|
|
|
friend RRColorComp operator-(const RRColorComp& A, const RRColorComp& B)
|
|
{
|
|
return RRColorComp( A.m_fVal - B.m_fVal );
|
|
}
|
|
friend RRColorComp operator-(const RRColorComp& A, FLOAT fB)
|
|
{
|
|
return RRColorComp( A.m_fVal - fB );
|
|
}
|
|
|
|
friend RRColorComp operator*(const RRColorComp& A, const RRColorComp& B)
|
|
{
|
|
return RRColorComp( A.m_fVal * B.m_fVal );
|
|
}
|
|
friend RRColorComp operator*(const RRColorComp& A, FLOAT fB)
|
|
{
|
|
return RRColorComp( A.m_fVal * fB );
|
|
}
|
|
RRColorComp& operator*=(const RRColorComp& A)
|
|
{
|
|
m_fVal *= A.m_fVal; return *this;
|
|
}
|
|
RRColorComp& operator*=(const UINT8 uA)
|
|
{
|
|
m_fVal *= ((1./255.)*(FLOAT)uA); return *this;
|
|
}
|
|
|
|
friend RRColorComp minimum(const RRColorComp& A, const RRColorComp& B)
|
|
{
|
|
return RRColorComp( min( A.m_fVal, B.m_fVal ) );
|
|
}
|
|
friend RRColorComp maximum(const RRColorComp& A, const RRColorComp& B)
|
|
{
|
|
return RRColorComp( max( A.m_fVal, B.m_fVal ) );
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Color Value Class - Holds an Alpha,Red,Green,Blue color value consisting of
|
|
// four RRColorComp objects.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class RRColor
|
|
{
|
|
public:
|
|
RRColorComp A;
|
|
RRColorComp R;
|
|
RRColorComp G;
|
|
RRColorComp B;
|
|
|
|
// default and UINT32 assignment constructor
|
|
RRColor( void ) : A(0.F), R(0.F), G(0.F), B(0.F) {;}
|
|
RRColor( UINT32 uVal ) :
|
|
A (UINT8( RGBA_GETALPHA( uVal ) )),
|
|
R (UINT8( RGBA_GETRED( uVal ) )),
|
|
G (UINT8( RGBA_GETGREEN( uVal ) )),
|
|
B (UINT8( RGBA_GETBLUE( uVal ) )) {;}
|
|
RRColor( FLOAT fR, FLOAT fG, FLOAT fB, FLOAT fA ) :
|
|
R(fR), G(fG), B(fB), A(fA) {;}
|
|
|
|
// UINT32 copy operator
|
|
void operator=(const UINT32 uVal) // TODO: implement proper assignment operator?
|
|
{
|
|
A = UINT8( RGBA_GETALPHA( uVal ) );
|
|
R = UINT8( RGBA_GETRED( uVal ) );
|
|
G = UINT8( RGBA_GETGREEN( uVal ) );
|
|
B = UINT8( RGBA_GETBLUE( uVal ) );
|
|
}
|
|
// casting operator
|
|
operator UINT32() const
|
|
{
|
|
return D3DRGBA( FLOAT(R), FLOAT(G), FLOAT(B), FLOAT(A) );
|
|
}
|
|
|
|
// methods to set all channels
|
|
void SetAllChannels( const RRColorComp& Val )
|
|
{
|
|
A = Val; R = Val; G = Val; B = Val;
|
|
}
|
|
void SetAllChannels( FLOAT fVal )
|
|
{
|
|
A = fVal; R = fVal; G = fVal; B = fVal;
|
|
}
|
|
|
|
//
|
|
// conversions between surface format and RRColor - these define the
|
|
// correct way to map between resolutions
|
|
//
|
|
|
|
// convert from surface type format to RRColor
|
|
void ConvertFrom( RRSurfaceType Type, const char* pSurfaceBits )
|
|
{
|
|
UINT16 u16BITS;
|
|
|
|
switch (Type)
|
|
{
|
|
default:
|
|
case RR_STYPE_NULL: return;
|
|
case RR_STYPE_B8G8R8A8: *this = *((UINT32*)pSurfaceBits); break;
|
|
case RR_STYPE_B8G8R8X8: *this = *((UINT32*)pSurfaceBits); A = 1.F; break;
|
|
|
|
case RR_STYPE_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 RR_STYPE_B5G5R5:
|
|
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 RR_STYPE_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 RR_STYPE_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 RR_STYPE_B8G8R8:
|
|
R = *((UINT8*)pSurfaceBits+2);
|
|
G = *((UINT8*)pSurfaceBits+1);
|
|
B = *((UINT8*)pSurfaceBits+0);
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RR_STYPE_L8:
|
|
R = G = B = *((UINT8*)pSurfaceBits);
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RR_STYPE_L8A8:
|
|
u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = G = B = (UINT8)(0xff & u16BITS);
|
|
A = (UINT8)(0xff & (u16BITS >> 8));
|
|
break;
|
|
|
|
case RR_STYPE_B2G3R3:
|
|
u16BITS = *((UINT8*)pSurfaceBits);
|
|
R = ((u16BITS>>(3+2)) & 0x07)/7.f;
|
|
G = ((u16BITS>> 2) & 0x07)/7.f;
|
|
B = ((u16BITS ) & 0x03)/3.f;
|
|
A = 1.F;
|
|
break;
|
|
|
|
case RR_STYPE_L4A4:
|
|
u16BITS = *((UINT8*)pSurfaceBits);
|
|
R = G = B = (u16BITS & 0x0f)/15.f;
|
|
A = ((u16BITS>>4) & 0x0f)/15.f;
|
|
break;
|
|
|
|
case RR_STYPE_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));
|
|
break;
|
|
|
|
case RR_STYPE_U8V8:
|
|
{
|
|
INT8 iDU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iDV = *(( INT8*)pSurfaceBits+1);
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = (FLOAT)iDU * (1.0F/128.0F); // fDU
|
|
G = (FLOAT)iDV * (1.0F/128.0F); // fDV
|
|
B = 1.0F; // fL
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_U5V5L6:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
INT8 iDU = (INT8)(u16BITS & 0x1f);
|
|
INT8 iDV = (INT8)((u16BITS>>5) & 0x1f);
|
|
UINT8 uL = (UINT8)(u16BITS >> 10);
|
|
iDU <<= 3; iDU >>= 3; // sign extension
|
|
iDV <<= 3; iDV >>= 3;
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = (FLOAT)iDU * (1.0F/16.0F); // fDU
|
|
G = (FLOAT)iDV * (1.0F/16.0F); // 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
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_U8V8L8:
|
|
{
|
|
INT8 iDU = *(( INT8*)pSurfaceBits+0);
|
|
INT8 iDV = *(( INT8*)pSurfaceBits+1);
|
|
UINT8 uL = *((UINT8*)pSurfaceBits+2);
|
|
// signed values are normalized with 2^(N-1), since -2^(N-1) can
|
|
// be exactly expressed in N bits
|
|
R = (FLOAT)iDU * (1.0F/128.0F); // fDU
|
|
G = (FLOAT)iDV * (1.0F/128.0F); // 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
|
|
}
|
|
break;
|
|
|
|
// shadow map texture formats (read only, not needed for ConvertTo)
|
|
case RR_STYPE_Z16S0:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)u16BITS * (1.0F/(FLOAT)0xffff);
|
|
B = 0.0F;
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_Z24S8:
|
|
case RR_STYPE_Z24S4:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u32BITS>>8) * (1.0F/(FLOAT)0xffffff);
|
|
B = 0.0F;
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_S8Z24:
|
|
case RR_STYPE_S4Z24:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u32BITS&0x00ffffff) * (1.0F/(FLOAT)0xffffff);
|
|
B = 0.0F;
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_Z15S1:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u16BITS>>1) * (1.0F/(FLOAT)0x7fff);
|
|
B = 0.0F;
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_S1Z15:
|
|
{
|
|
UINT16 u16BITS = *((UINT16*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)(u16BITS&0x7fff) * (1.0F/(FLOAT)0x7fff);
|
|
B = 0.0F;
|
|
}
|
|
break;
|
|
|
|
case RR_STYPE_Z32S0:
|
|
{
|
|
UINT32 u32BITS = *((UINT32*)pSurfaceBits);
|
|
R = 0.0F;
|
|
G = (FLOAT)u32BITS * (1.0F/(FLOAT)0xffffffff);
|
|
B = 0.0F;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Convert surface type format to RRColor
|
|
void ConvertTo( RRSurfaceType Type, float fRoundOffset, char* pSurfaceBits ) const
|
|
{
|
|
int iR, iG, iB, iA;
|
|
|
|
switch (Type)
|
|
{
|
|
case RR_STYPE_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 RR_STYPE_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 RR_STYPE_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 RR_STYPE_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 RR_STYPE_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 RR_STYPE_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 RR_STYPE_B5G5R5:
|
|
iR = (FLOAT)R * 31. + fRoundOffset;
|
|
iG = (FLOAT)G * 31. + fRoundOffset;
|
|
iB = (FLOAT)B * 31. + fRoundOffset;
|
|
*((UINT16*)pSurfaceBits) = (iR<<10) | (iG<<5) | iB;
|
|
break;
|
|
|
|
case RR_STYPE_B2G3R3:
|
|
iR = (FLOAT)R * 7. + fRoundOffset;
|
|
iG = (FLOAT)G * 7. + fRoundOffset;
|
|
iB = (FLOAT)B * 3. + fRoundOffset;
|
|
*((UINT8*)pSurfaceBits) = (iR<<5) | (iG<<2) | iB;
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RRDepth - Class for storing and manipulating pixel depth values. Underlying
|
|
// storage is a double precision floating point, which has sufficient precision
|
|
// and range to support 16 and 32 bit fixed point and 32 bit floating point.
|
|
//
|
|
// The UINT32 methods receive a 24 or 32 bit value, and the UINT16
|
|
// methods receive a 15 or 16 bit value.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class RRDepth
|
|
{
|
|
DOUBLE m_dVal;
|
|
RRSurfaceType m_DepthSType;
|
|
DOUBLE dGetValClamped(void) const { return min(1.,max(0.,m_dVal)); }
|
|
DOUBLE dGetCnvScale(void) const
|
|
{
|
|
switch(m_DepthSType)
|
|
{
|
|
case RR_STYPE_Z16S0:
|
|
return DOUBLE((1<<16)-1);
|
|
case RR_STYPE_Z24S8:
|
|
case RR_STYPE_S8Z24:
|
|
case RR_STYPE_Z24S4:
|
|
case RR_STYPE_S4Z24:
|
|
return DOUBLE((1<<24)-1);
|
|
case RR_STYPE_Z15S1:
|
|
case RR_STYPE_S1Z15:
|
|
return DOUBLE((1<<15)-1);
|
|
case RR_STYPE_Z32S0:
|
|
return DOUBLE(0xffffffff); // too big to be generated as above without INT64's
|
|
default:
|
|
DPFRR(0, "RRDepth not initialized correctly");
|
|
return DOUBLE(0.0);
|
|
}
|
|
}
|
|
public:
|
|
// default and UINT16/32 assignment constructor
|
|
// default only for Pixel class, and requires that SetSType be called later
|
|
RRDepth() : m_dVal(0.F), m_DepthSType(RR_STYPE_NULL) {;}
|
|
RRDepth(RRSurfaceType SType) : m_dVal(0.F), m_DepthSType(SType) {;}
|
|
RRDepth(UINT16 uVal, RRSurfaceType SType): m_DepthSType(SType), m_dVal((DOUBLE)uVal/dGetCnvScale()) {;}
|
|
RRDepth(UINT32 uVal, RRSurfaceType SType): m_DepthSType(SType), m_dVal((DOUBLE)uVal/dGetCnvScale()) {;}
|
|
|
|
// copy and assignment operators
|
|
RRDepth& operator=(const RRDepth& A) { m_dVal = A.m_dVal; m_DepthSType = A.m_DepthSType; return *this; }
|
|
RRDepth& operator=(UINT16 uVal) { m_dVal = (DOUBLE)uVal/dGetCnvScale(); return *this; }
|
|
RRDepth& operator=(UINT32 uVal) { m_dVal = (DOUBLE)uVal/dGetCnvScale(); return *this; }
|
|
RRDepth& operator=(FLOAT fVal) { m_dVal = (DOUBLE)fVal; return *this; }
|
|
|
|
// round for integer get operations
|
|
operator UINT16() const { return (UINT16)( (dGetValClamped()*dGetCnvScale()) + .5); }
|
|
operator UINT32() const { return (UINT32)( (dGetValClamped()*dGetCnvScale()) + .5); }
|
|
|
|
operator DOUBLE() const { return dGetValClamped(); }
|
|
operator FLOAT() const { return (FLOAT)dGetValClamped(); }
|
|
void SetSType(RRSurfaceType SType) { m_DepthSType = SType; }
|
|
RRSurfaceType GetSType(void) const { return m_DepthSType; }
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RRPixel - Class for encapsulation of all pixel information passed from
|
|
// scan conversion to pixel and fragment processing.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class RRPixel
|
|
{
|
|
public:
|
|
INT16 iX; // pixel location
|
|
INT16 iY; //
|
|
RRColor Color; // pixel diffuse color
|
|
RRColor Specular; // pixel specular color (rgb only - alpha unused)
|
|
RRDepth Depth; // pixel depth
|
|
FLOAT fW; // pixel W value (unnormalized)
|
|
RRColorComp FogIntensity; // fog intensity (scalar)
|
|
RRCvgMask CvgMask; // coverage mask
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Setup & Scan Convert //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Scan Converter State - Holds input and current state of scan converter.
|
|
// Filled in by setup.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
struct _RRSCANCNVSTATE
|
|
{
|
|
// primitive vertex data
|
|
FLOAT fX0, fY0, fRHW0;
|
|
FLOAT fX1, fY1, fRHW1;
|
|
FLOAT fX2, fY2, fRHW2;
|
|
// primitive transformed texture coord data
|
|
FLOAT fTexCoord[D3DHAL_TSS_MAXSTAGES][3][4];
|
|
FLOAT fRHQW[D3DHAL_TSS_MAXSTAGES][3];
|
|
BOOL bWrap[D3DHAL_TSS_MAXSTAGES][4];
|
|
|
|
// x,y deltas
|
|
FLOAT fDelX10, fDelX02, fDelX21;
|
|
FLOAT fDelY01, fDelY20, fDelY12;
|
|
|
|
// triangle edge functions and gradient data
|
|
RREdgeFunc EdgeFuncs[4]; // A,B,C values and A,B sign bits for 4 edges
|
|
// the fourth edge is only used to scan convert points
|
|
|
|
// triangle bounding box
|
|
INT16 iXMin, iXMax;
|
|
INT16 iYMin, iYMax;
|
|
|
|
// line drawing data
|
|
INT64 iLineEdgeFunc[3]; // line function: Pminor = ([0]*Pmajor + [1])/[2]
|
|
BOOL bXMajor; // TRUE if X major; else Y major
|
|
INT16 iLineMin, iLineMax; // min and max pixel extent in major direction
|
|
INT16 iLineStep; // +1 or -1 depending on line major direction
|
|
|
|
// depth range for primitive (for clamp when sampling outside primitive area)
|
|
// may be Z or W
|
|
FLOAT fDepthMin, fDepthMax;
|
|
|
|
//
|
|
// attribute functions - static (per-primitive) data, non-texture,
|
|
// and texture functions
|
|
//
|
|
RRAttribFuncStatic AttribFuncStatic;
|
|
|
|
#define ATTRFUNC_R 0
|
|
#define ATTRFUNC_G 1
|
|
#define ATTRFUNC_B 2
|
|
#define ATTRFUNC_A 3
|
|
#define ATTRFUNC_SR 4
|
|
#define ATTRFUNC_SG 5
|
|
#define ATTRFUNC_SB 6
|
|
#define ATTRFUNC_SA 7
|
|
#define ATTRFUNC_F 8
|
|
#define ATTRFUNC_Z 9
|
|
#define RR_N_ATTRIBS 10
|
|
RRAttribFunc AttribFuncs[RR_N_ATTRIBS];
|
|
|
|
#define TEXFUNC_0 0
|
|
#define TEXFUNC_1 1
|
|
#define TEXFUNC_2 2
|
|
#define TEXFUNC_3 3
|
|
#define RR_N_TEX_ATTRIBS 4
|
|
RRAttribFunc TextureFuncs[D3DHAL_TSS_MAXSTAGES][RR_N_TEX_ATTRIBS];
|
|
|
|
|
|
//
|
|
// per-pixel data
|
|
//
|
|
|
|
// current position
|
|
INT16 iX,iY;
|
|
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Texture
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
// structure containing texture coordinate and gradient information
|
|
// for lookup and filtering
|
|
//
|
|
class RRTextureCoord
|
|
{
|
|
public:
|
|
FLOAT fU; // texture coordinate
|
|
FLOAT fV;
|
|
FLOAT fDUDX; // texture gradient dU/dX
|
|
FLOAT fDUDY; // texture gradient dU/dY
|
|
FLOAT fDVDX; // texture gradient dV/dX
|
|
FLOAT fDVDY; // texture gradient dV/dY
|
|
};
|
|
|
|
//
|
|
// structure containing normal and gradient information
|
|
// for environment map lookup and filtering
|
|
//
|
|
class RREnvTextureCoord
|
|
{
|
|
public:
|
|
FLOAT fNX; // normal or reflection normal
|
|
FLOAT fNY;
|
|
FLOAT fNZ;
|
|
// FLOAT fENX; // eye normal
|
|
// FLOAT fENY;
|
|
// FLOAT fENZ;
|
|
FLOAT fDNXDX; // normal gradient dNX/dX
|
|
FLOAT fDNXDY; // normal gradient dNX/dY
|
|
FLOAT fDNYDX; // normal gradient dNY/dX
|
|
FLOAT fDNYDY; // normal gradient dNY/dY
|
|
FLOAT fDNZDX; // normal gradient dNZ/dX
|
|
FLOAT fDNZDY; // normal gradient dNZ/dY
|
|
};
|
|
|
|
//
|
|
// routines to compute level of detail (texel->pixel coverage)
|
|
//
|
|
// (texfilt.cpp)
|
|
void
|
|
ComputeSimpleLevelOfDetail(
|
|
const RRTextureCoord& TCoord, // inputs
|
|
FLOAT& fLOD ); // outputs
|
|
|
|
void
|
|
ComputeEnvMapLevelOfDetail(
|
|
const RRTextureCoord& TCoord, // inputs
|
|
FLOAT& fLOD ); // outputs
|
|
|
|
void
|
|
ComputeAnisotropicLevelOfDetail(
|
|
const RRTextureCoord& TCoord, FLOAT fMaxAniso, // inputs
|
|
FLOAT& fLOD, FLOAT& fRatio, FLOAT fDelta[] ); // outputs
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// Pixel Engine //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// coverage mask values
|
|
#define TL_CVGFULL 0xffff
|
|
#define TL_CVGZERO 0x0000
|
|
#define TL_CVGBITS 16
|
|
#define TL_CVGBITSm 4
|
|
|
|
typedef UINT16 CVGMASK;
|
|
|
|
// fragment - fragmented pixels have linked lists of these
|
|
struct _RRFRAGMENT
|
|
{
|
|
RRColor Color;
|
|
RRDepth Depth;
|
|
CVGMASK CvgMask;
|
|
void* pNext;
|
|
};
|
|
|
|
int CountFrags(RRFRAGMENT* pFrag);
|
|
void DPFFrags(RRFRAGMENT* pFrag);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Fragment Resolution Accumulator - accumulates fragments presented in
|
|
// front-to-back order; does fully correct transparency computations for
|
|
// non-opaque fragments
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class FragResolveAccum
|
|
{
|
|
public:
|
|
// coverage accumulation array - holds up to CVGBITS different
|
|
// alpha values and associated coverage masks; UsageMask indicates
|
|
// which entries are currently in use - each set bit in Usage mask
|
|
// indicates that the array entry corresponding to the index of the
|
|
// that bit holds a valid mask and alpha;
|
|
//
|
|
// the general idea here is that, in cases in which there are few
|
|
// fragments, numerous sample locations (within the pixel) will have
|
|
// the same alpha value, and thus can be grouped for the accumulation
|
|
struct {
|
|
CVGMASK Mask;
|
|
FLOAT fAlpha;
|
|
} m_CvgArray[TL_CVGBITS];
|
|
CVGMASK m_ArrayUsageMask;
|
|
|
|
// accumulated color and alpha value
|
|
FLOAT m_fA, m_fR, m_fG, m_fB;
|
|
|
|
// mask where set bit indicates a subpixel with opaque alpha
|
|
CVGMASK m_CvgOpaqueMask;
|
|
|
|
// reset before each use...
|
|
void Reset( void );
|
|
|
|
// accumulate new fragment (front to back) - returns TRUE if
|
|
// full coverage achieved, FALSE otherwise
|
|
BOOL Accum( const CVGMASK CvgMask, const RRColor& Color );
|
|
|
|
// get RRColor from accumulator
|
|
void GetColor( RRColor& Color );
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// statistics
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
struct _RRSTATS
|
|
{
|
|
INT32 cFragsAllocd;
|
|
INT32 cMaxFragsAllocd;
|
|
INT32 cFragsMerged;
|
|
INT32 cFragsMergedToFull;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// utilities
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// compute pixel address from base, pitch, and surface type
|
|
char*
|
|
PixelAddress( int iX, int iY, char* pBits, int iYPitch, RRSurfaceType SType );
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// color interpolation utilities
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void LerpColor(RRColor& Color,
|
|
const RRColor& Color0, const RRColor& Color1, UINT8 uT);
|
|
void BiLerpColor( RRColor& OutColor,
|
|
const RRColor& Color00, const RRColor& Color01,
|
|
const RRColor& Color10, const RRColor& Color11,
|
|
UINT8 uA, UINT8 uB);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Globals
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// something to experiment with sometime - this sets the threshold at which
|
|
// pixel samples are considered opaque (and thus don't generate fragment
|
|
// buffer entries when doing D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT);
|
|
// no need to have all those 0xfe's generate fragments...
|
|
extern UINT8 g_uTransparencyAlphaThreshold;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// One special legacy texture op we can't easily map into the new texture
|
|
// ops.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define D3DTOP_LEGACY_ALPHAOVR (0x7fffffff)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#endif // _REFRASTI_HPP
|