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.
964 lines
32 KiB
964 lines
32 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (C) Microsoft Corporation, 1998.
|
|
//
|
|
// reftnl.hpp
|
|
//
|
|
// Direct3D Reference Transform and Lighting - Main Header File
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef _REFTNL_HPP
|
|
#define _REFTNL_HPP
|
|
|
|
#define RD_GB_LEFT -32768.f
|
|
#define RD_GB_TOP -32768.f
|
|
#define RD_GB_RIGHT 32767.f
|
|
#define RD_GB_BOTTOM 32767.f
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Constants
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// Default color values that should be used when ther is no lighting and
|
|
// color in vertices provided
|
|
const DWORD RD_DEFAULT_DIFFUSE = 0xFFFFFFFF;
|
|
const DWORD RD_DEFAULT_SPECULAR = 0;
|
|
|
|
const DWORD RD_MAX_FVF_TEXCOORD = 8;
|
|
|
|
const DWORD RD_MAX_VERTEX_COUNT = 2048;
|
|
|
|
// Number of clipping planes
|
|
const DWORD RD_MAX_USER_CLIPPLANES = 6;
|
|
|
|
// Number of clipping planes
|
|
const DWORD RD_MAX_CLIPPING_PLANES = (6+RD_MAX_USER_CLIPPLANES);
|
|
|
|
// Number of blend weights
|
|
const DWORD RD_MAX_BLEND_WEIGHTS = 4;
|
|
|
|
// Number of world matrices
|
|
const DWORD RD_MAX_WORLD_MATRICES = 256;
|
|
|
|
const DWORD RD_WORLDMATRIXBASE = 256;
|
|
|
|
// Space for vertices generated/copied while clipping one triangle
|
|
const DWORD RD_MAX_CLIP_VERTICES = (( 2 * RD_MAX_CLIPPING_PLANES ) + 3 );
|
|
|
|
// 3 verts. -> 1 tri, 4 v -> 2 t, N vertices -> (N - 2) triangles
|
|
const DWORD RD_MAX_CLIP_TRIANGLES = ( RD_MAX_CLIP_VERTICES - 2 );
|
|
|
|
// make smaller than guard band for easier clipping
|
|
const float RD_MAX_POINT_SIZE = 64;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Forward defines
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
class RDLight;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Typedefs
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
typedef DWORD RDCLIPCODE;
|
|
typedef D3DMATRIX RDMATRIX;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RDVertex - Internal vertex structure of the refrast. This is the
|
|
// structure exchanged between the T&L and Rasterization parts
|
|
// of the refrast.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class RDVertex
|
|
{
|
|
public:
|
|
RDVertex()
|
|
{
|
|
Init();
|
|
}
|
|
|
|
RDVertex( LPDWORD pVtx, DWORD dwFvf )
|
|
{
|
|
SetFvfData( pVtx, (UINT64)dwFvf );
|
|
}
|
|
|
|
RDVertex( LPDWORD pVtx, UINT64 qwFvf )
|
|
{
|
|
SetFvfData( pVtx, qwFvf );
|
|
}
|
|
|
|
RDCLIPCODE m_clip;
|
|
FLOAT m_clip_x;
|
|
FLOAT m_clip_y;
|
|
FLOAT m_clip_z;
|
|
FLOAT m_clip_w;
|
|
RDVECTOR3 m_pos; // This is screen coordinates
|
|
FLOAT m_rhw;
|
|
RDCOLOR4 m_diffuse; // ARGB (0..1 each component)
|
|
RDCOLOR4 m_specular; // ARGB
|
|
FLOAT m_fog; // 0..1
|
|
FLOAT m_pointsize;
|
|
RDVECTOR4 m_tex[8];
|
|
|
|
UINT64 m_qwFVF;
|
|
|
|
void Init()
|
|
{
|
|
m_clip = 0;
|
|
m_clip_x = m_clip_y = m_clip_z = m_clip_w = 0.0f;
|
|
m_rhw = 0.0f;
|
|
m_diffuse.a = m_diffuse.r = m_diffuse.g = m_diffuse.b = 1.0f;
|
|
m_specular.a = m_specular.r = m_specular.g = m_specular.b = 0.0f;
|
|
m_fog = 0.0f;
|
|
m_pointsize = 1.0f;
|
|
// Initialize texture coordinates to {0.0, 0.0, 0.0, 1.0}
|
|
memset( m_tex, 0, sizeof(m_tex) );
|
|
for( int i=0; i<8; i++ ) m_tex[i].w = 1.0f;
|
|
m_qwFVF = 0;
|
|
}
|
|
|
|
void SetFVF( UINT64 qwControl )
|
|
{
|
|
m_qwFVF = qwControl;
|
|
}
|
|
|
|
void SetFvfData( LPDWORD pVtx, UINT64 qwFVF )
|
|
{
|
|
DWORD cDWORD = 0;
|
|
Init();
|
|
m_qwFVF = qwFVF;
|
|
switch( qwFVF & D3DFVF_POSITION_MASK )
|
|
{
|
|
case D3DFVF_XYZRHW:
|
|
memcpy( &m_pos, pVtx, 3*sizeof( float ) );
|
|
pVtx += 3;
|
|
m_rhw = *(float *)(pVtx);
|
|
pVtx += 1;
|
|
break;
|
|
default:
|
|
_ASSERT( TRUE, "RDVertex can only hold Transformed Vertices" );
|
|
return;
|
|
}
|
|
|
|
if (qwFVF & D3DFVF_PSIZE)
|
|
{
|
|
m_pointsize = *(FLOAT*)pVtx;
|
|
pVtx++;
|
|
}
|
|
if (qwFVF & D3DFVF_DIFFUSE)
|
|
{
|
|
MakeRDCOLOR4( &m_diffuse, *pVtx );
|
|
pVtx++;
|
|
}
|
|
if (qwFVF & D3DFVF_SPECULAR)
|
|
{
|
|
MakeRDCOLOR4( &m_specular, *pVtx );
|
|
m_fog = m_specular.a;
|
|
m_qwFVF |= D3DFVFP_FOG;
|
|
pVtx++;
|
|
}
|
|
if (qwFVF & D3DFVF_FOG)
|
|
{
|
|
m_fog = *(FLOAT*)pVtx;
|
|
m_qwFVF |= D3DFVFP_FOG;
|
|
pVtx++;
|
|
}
|
|
DWORD dwNumTexCoord = (DWORD)(FVF_TEXCOORD_NUMBER(qwFVF));
|
|
DWORD dwTextureFormats = (DWORD)qwFVF >> 16;
|
|
|
|
// Texture formats size 00 01 10 11
|
|
static DWORD dwTextureSize[4] = {2, 3, 4, 1};
|
|
for (DWORD i=0; i < dwNumTexCoord; i++)
|
|
{
|
|
memcpy( &m_tex[i], pVtx,
|
|
sizeof( float )*dwTextureSize[dwTextureFormats & 3] );
|
|
pVtx += dwTextureSize[dwTextureFormats & 3];
|
|
dwTextureFormats >>= 2;
|
|
}
|
|
}
|
|
|
|
FLOAT GetRHW( void ) const
|
|
{
|
|
return ( m_qwFVF & D3DFVF_XYZRHW ) ? m_rhw : 1.f ;
|
|
}
|
|
|
|
FLOAT* GetPtrXYZ( void ) { return (FLOAT*)&m_pos; }
|
|
FLOAT GetX( void ) const { return m_pos.x; }
|
|
FLOAT GetY( void ) const { return m_pos.y; }
|
|
FLOAT GetZ( void ) const { return m_pos.z; }
|
|
DWORD GetDiffuse( void ) const
|
|
{
|
|
DWORD diff =
|
|
D3DRGBA(m_diffuse.r, m_diffuse.g, m_diffuse.b, m_diffuse.a);
|
|
// return color if available else white (default)
|
|
return ( m_qwFVF & D3DFVF_DIFFUSE ) ? diff : 0xffffffff;
|
|
}
|
|
|
|
DWORD GetSpecular( void ) const
|
|
{
|
|
DWORD spec =
|
|
D3DRGBA(m_specular.r, m_specular.g, m_specular.b, m_specular.a);
|
|
// return color if available else black (default)
|
|
return ( m_qwFVF & D3DFVF_SPECULAR ) ? spec : 0x00000000;
|
|
}
|
|
|
|
UINT TexCrdCount( void ) const
|
|
{
|
|
return
|
|
(UINT)(( m_qwFVF & D3DFVF_TEXCOUNT_MASK ) >> D3DFVF_TEXCOUNT_SHIFT);
|
|
}
|
|
|
|
FLOAT GetTexCrd( UINT iCrd, UINT iCrdSet ) const
|
|
{
|
|
// This function ensures that right defaults are returned.
|
|
// Note, except for the q coordinate (which defaults to 1.0)
|
|
// the rest are 0.0.
|
|
if( (iCrdSet < TexCrdCount()) &&
|
|
(iCrd < GetTexCoordDim(m_qwFVF, iCrdSet)) )
|
|
{
|
|
return *( (FLOAT*)&m_tex[iCrdSet] + iCrd );
|
|
}
|
|
else if( iCrd == 3 )
|
|
{
|
|
return 1.0f;
|
|
}
|
|
else
|
|
{
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
FLOAT GetLastTexCrd( UINT iCrdSet ) const
|
|
{
|
|
// Return the last texture coordinate if present else 1.0
|
|
if( iCrdSet < TexCrdCount() )
|
|
{
|
|
return *( (FLOAT*)&m_tex[iCrdSet] +
|
|
GetTexCoordDim(m_qwFVF, iCrdSet) - 1);
|
|
}
|
|
else
|
|
{
|
|
return 1.0f;
|
|
}
|
|
}
|
|
|
|
FLOAT GetPointSize( void ) const
|
|
{
|
|
return ( m_qwFVF & D3DFVF_PSIZE ) ? m_pointsize : 1.0f;
|
|
}
|
|
|
|
FLOAT GetFog( void ) const
|
|
{
|
|
return ( m_qwFVF & D3DFVFP_FOG ) ? m_fog : 0.0f;
|
|
}
|
|
};
|
|
|
|
class RDClipVertex : public RDVertex
|
|
{
|
|
public:
|
|
RDClipVertex()
|
|
{
|
|
next = NULL;
|
|
}
|
|
|
|
RDClipVertex *next;
|
|
};
|
|
|
|
struct RDCLIPTRIANGLE
|
|
{
|
|
RDCLIPTRIANGLE()
|
|
{
|
|
memset( this, 0, sizeof(*this) );
|
|
}
|
|
|
|
RDClipVertex *v[3];
|
|
};
|
|
|
|
struct RDUSERCLIPPLANE
|
|
{
|
|
RDUSERCLIPPLANE()
|
|
{
|
|
memset( this, 0, sizeof(*this) );
|
|
}
|
|
|
|
RDVECTOR4 plane;
|
|
BOOL bActive;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RDTRANSFORMDATA - Transformation data used by Refrence T&L implementation
|
|
// to transform vertices.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
struct RDTRANSFORMDATA
|
|
{
|
|
RDTRANSFORMDATA()
|
|
{
|
|
memset( this, 0, sizeof(*this) );
|
|
}
|
|
|
|
RDMATRIX m_PS; // Mproj * Mshift
|
|
RDMATRIX m_VPS; // Mview * PS
|
|
RDMATRIX m_VPSInv; // Inverse( Mview * PS )
|
|
RDMATRIX m_CTMI; // Inverse current transformation matrix
|
|
RDVECTOR4 m_frustum[6]; // Normalized plane equations for viewing
|
|
// frustum in the model space
|
|
DWORD m_dwFlags;
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// RDLIGHTINGDATA
|
|
// All the lighting related state clubbed together
|
|
//---------------------------------------------------------------------
|
|
|
|
struct RDLIGHTINGDATA
|
|
{
|
|
RDLIGHTINGDATA()
|
|
{
|
|
memset( this, 0, sizeof(*this) );
|
|
}
|
|
|
|
// Active Light list
|
|
RDLight *pActiveLights;
|
|
|
|
// Temporary data used when computing lighting
|
|
|
|
RDVECTOR3 eye_in_eye; // eye position in eye space
|
|
// It is (0, 0, 0)
|
|
|
|
// Ma * La + Me (Ambient and Emissive) ------
|
|
RDCOLOR3 ambEmiss;
|
|
|
|
// ColorVertex stuff ------------------------
|
|
RDCOLOR3 *pAmbientSrc;
|
|
RDCOLOR3 *pDiffuseSrc;
|
|
RDCOLOR3 *pSpecularSrc;
|
|
RDCOLOR3 *pEmissiveSrc;
|
|
|
|
// Diffuse ----------------------------------
|
|
RDCOLOR3 vertexDiffuse; // Provided with a vertex, used if
|
|
// COLORVERTEX is enabled and a diffuse
|
|
// color is provided in the vertex
|
|
RDCOLOR3 diffuse; // Diffuse accumulates here
|
|
DWORD outDiffuse; // Diffuse color result of lighting
|
|
|
|
|
|
// Specular --------------------------------
|
|
RDCOLOR3 vertexSpecular;// Provided with a vertex, used if
|
|
// COLORVERTEX is enabled and a specular
|
|
// color is provided in the vertex
|
|
RDCOLOR3 specular; // Specular accumulates here
|
|
DWORD outSpecular; // Specular color result of lighting
|
|
|
|
D3DVALUE specThreshold; // If the dot product is less than this
|
|
// value, specular factor is zero
|
|
// End of temporary data
|
|
|
|
// RENDERSTATEAMBIENT --------------------------------------
|
|
|
|
// Ambient color set by D3DRENDERSTATE_AMBIENT
|
|
// They are all scaled to 0 - 1
|
|
D3DVALUE ambient_red;
|
|
D3DVALUE ambient_green;
|
|
D3DVALUE ambient_blue;
|
|
DWORD ambient_save; // Original unscaled color
|
|
|
|
// Fog -----------------------------------------------------
|
|
int fog_mode;
|
|
D3DCOLOR fog_color;
|
|
D3DVALUE fog_density;
|
|
D3DVALUE fog_start;
|
|
D3DVALUE fog_end;
|
|
D3DVALUE fog_factor; // 255 / (fog_end - fog_start)
|
|
|
|
D3DCOLORMODEL color_model;
|
|
|
|
// Material ------------------------------------------------
|
|
|
|
// For color material
|
|
LPDWORD pDiffuseAlphaSrc;
|
|
LPDWORD pSpecularAlphaSrc;
|
|
|
|
DWORD materialDiffAlpha; // Current material diffuse
|
|
// alpha (0-255) shifted left
|
|
// by 24 bits
|
|
|
|
DWORD materialSpecAlpha; // Current material specular
|
|
// alpha (0-255) shifted left
|
|
// by 24 bits
|
|
|
|
DWORD vertexDiffAlpha; // Current material diffuse
|
|
// alpha (0-255) shifted left
|
|
// by 24 bits
|
|
|
|
DWORD vertexSpecAlpha; // Current material specular
|
|
// alpha (0-255) shifted left
|
|
// by 24 bits
|
|
|
|
D3DMATERIAL7 material; // Cached material data
|
|
RDCOLOR3 matAmb;
|
|
RDCOLOR3 matDiff;
|
|
RDCOLOR3 matSpec;
|
|
RDCOLOR3 matEmis;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RDLight - The light object used by the Reference T&L implementation
|
|
// An array of these are instanced in the RefDev object.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
struct RDLIGHTI
|
|
{
|
|
RDLIGHTI()
|
|
{
|
|
memset( this, 0, sizeof(*this) );
|
|
}
|
|
|
|
DWORD flags;
|
|
|
|
RDVECTOR3 position_in_eye; // In the eye space
|
|
RDVECTOR3 direction_in_eye; // In the eye space
|
|
|
|
//
|
|
// Saved light colors scaled from 0 - 255, needed for COLORVERTEX
|
|
//
|
|
D3DCOLORVALUE La; // light ambient
|
|
D3DCOLORVALUE Ld; // light diffuse
|
|
D3DCOLORVALUE Ls; // light specular
|
|
|
|
//
|
|
// Precomputed colors scaled from 0 - 255,
|
|
//
|
|
D3DCOLORVALUE Ma_La; // Material ambient times light ambient
|
|
D3DCOLORVALUE Md_Ld; // Material diffuse times light diffuse
|
|
D3DCOLORVALUE Ms_Ls; // Material specular times light specular
|
|
|
|
|
|
RDVECTOR3 halfway;
|
|
|
|
// Stuff for SpotLights
|
|
D3DVALUE range_squared;
|
|
D3DVALUE cos_theta_by_2;
|
|
D3DVALUE cos_phi_by_2;
|
|
D3DVALUE inv_theta_minus_phi;
|
|
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Function pointer to the functions that light a vertex
|
|
//-----------------------------------------------------------------------------
|
|
typedef void (*RDLIGHTVERTEXFN)( RDLIGHTINGDATA& LData, D3DLIGHT7 *pLight,
|
|
RDLIGHTI *pLightI, RDLIGHTINGELEMENT *in,
|
|
DWORD dwFlags, UINT64 qwFVFIn );
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Functions to compute lighting
|
|
//-----------------------------------------------------------------------------
|
|
struct RDLIGHTVERTEX_FUNC_TABLE
|
|
{
|
|
RDLIGHTVERTEX_FUNC_TABLE()
|
|
{
|
|
memset( this, 0, sizeof(*this) );
|
|
}
|
|
|
|
RDLIGHTVERTEXFN pfnDirectional;
|
|
RDLIGHTVERTEXFN pfnParallelPoint;
|
|
RDLIGHTVERTEXFN pfnSpot;
|
|
RDLIGHTVERTEXFN pfnPoint;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RDLight - The light object used by the Reference T&L implementation
|
|
// An array of these are instanced in the RefDev object.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
#define RDLIGHT_ENABLED 0x00000001 // Is the light active
|
|
#define RDLIGHT_NEEDSPROCESSING 0x00000002 // Is the light data processed
|
|
#define RDLIGHT_REFERED 0x00000004 // Has the light been refered
|
|
// to
|
|
|
|
class RDLight : public RDAlloc
|
|
{
|
|
public:
|
|
RDLight();
|
|
BOOL IsEnabled() {return (m_dwFlags & RDLIGHT_ENABLED);}
|
|
BOOL NeedsProcessing() {return (m_dwFlags & RDLIGHT_NEEDSPROCESSING);}
|
|
BOOL IsRefered() { return (m_dwFlags & RDLIGHT_REFERED); }
|
|
HRESULT SetLight(LPD3DLIGHT7 pLight);
|
|
HRESULT GetLight( LPD3DLIGHT7 pLight );
|
|
void ProcessLight( D3DMATERIAL7 *mat, RDLIGHTVERTEX_FUNC_TABLE *pTbl);
|
|
void XformLight( D3DMATRIX* mV );
|
|
void Enable( RDLight **ppRoot );
|
|
void Disable( RDLight **ppRoot );
|
|
|
|
private:
|
|
|
|
// Flags
|
|
DWORD m_dwFlags;
|
|
|
|
// Active List next element
|
|
RDLight *m_Next;
|
|
|
|
// Specific function to light the vertex
|
|
RDLIGHTVERTEXFN m_pfnLightVertex;
|
|
|
|
// Light data set by the runtime
|
|
D3DLIGHT7 m_Light;
|
|
|
|
// Light data computed by the driver
|
|
RDLIGHTI m_LightI;
|
|
|
|
friend class RefDev;
|
|
friend class RefVP;
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// The clipper object. Contains digested Viewport information
|
|
// calculated from viewport settings.
|
|
//
|
|
//---------------------------------------------------------------------
|
|
class RefClipper
|
|
{
|
|
public:
|
|
RefClipper();
|
|
|
|
// The pointer to the driver object to obtain state
|
|
RefDev* m_pDev;
|
|
|
|
// m_dwDirtyFlags
|
|
static const DWORD RCLIP_DIRTY_ZRANGE;
|
|
static const DWORD RCLIP_DIRTY_VIEWRECT;
|
|
static const DWORD RCLIP_DO_FLATSHADING;
|
|
static const DWORD RCLIP_DO_WIREFRAME;
|
|
static const DWORD RCLIP_DO_ADJUSTWRAP;
|
|
static const DWORD RCLIP_Z_ENABLE;
|
|
DWORD m_dwFlags;
|
|
|
|
// Viewport data from the DDI.
|
|
D3DVIEWPORT7 m_Viewport;
|
|
|
|
// Is it guardband or not ?
|
|
BOOL m_bUseGB;
|
|
|
|
D3DVALUE dvX; // dwX
|
|
D3DVALUE dvY; // dwY
|
|
D3DVALUE dvWidth; // dwWidth
|
|
D3DVALUE dvHeight; // dwHeight
|
|
|
|
// Coefficients to compute screen coordinates from normalized window
|
|
// coordinates
|
|
D3DVALUE scaleX; // dvWidth/2
|
|
D3DVALUE scaleY; // dvHeight/2
|
|
D3DVALUE scaleZ; // (Viewport->dvMaxZ - Viewport->dvMinZ)
|
|
D3DVALUE offsetX; // dvX + scaleX
|
|
D3DVALUE offsetY; // dvY + scaleY
|
|
D3DVALUE offsetZ; // Viewport->dvMinZ
|
|
|
|
// Coefficients to compute screen coordinates from normalized window
|
|
// coordinates
|
|
D3DVALUE scaleXi; // Inverse of scaleX
|
|
D3DVALUE scaleYi; // Inverse of scaleY
|
|
D3DVALUE scaleZi; // Inverse of scaleZ
|
|
|
|
// Min and max values for viewport window in pixels
|
|
D3DVALUE minX; // offsetX - scaleX
|
|
D3DVALUE minY; // offsetY - scaleY
|
|
D3DVALUE maxX; // offsetX + scaleX
|
|
D3DVALUE maxY; // offsetY + scaleY
|
|
|
|
// Min and max window values with guard band in pixels
|
|
D3DVALUE minXgb;
|
|
D3DVALUE minYgb;
|
|
D3DVALUE maxXgb;
|
|
D3DVALUE maxYgb;
|
|
|
|
// Coefficients to transform a vertex to perform the guard band clipping
|
|
// x*gb11 + w*gb41
|
|
// y*gb22 + w*gb42
|
|
//
|
|
D3DVALUE gb11;
|
|
D3DVALUE gb22;
|
|
D3DVALUE gb41;
|
|
D3DVALUE gb42;
|
|
|
|
// Coefficients to apply clipping rules for the guard band clipping
|
|
// They are used by clipping routins
|
|
// w*Kgbx1 < x < w*Kgbx2
|
|
// w*Kgby1 < y < w*Kgby2
|
|
//
|
|
D3DVALUE Kgbx1;
|
|
D3DVALUE Kgby1;
|
|
D3DVALUE Kgbx2;
|
|
D3DVALUE Kgby2;
|
|
|
|
|
|
// Clipping related
|
|
RDCLIPCODE m_clipUnion; // OR of all vertex clip flags
|
|
RDCLIPCODE m_clipIntersection; // AND of all vertex clip flags
|
|
|
|
GArrayT<RDVertex> ClipBuf;
|
|
RDClipVertex *clip_vbuf1[RD_MAX_CLIP_VERTICES];
|
|
RDClipVertex *clip_vbuf2[RD_MAX_CLIP_VERTICES];
|
|
RDClipVertex **current_vbuf; // clip_vbuf1 or clip_vbuf2
|
|
RDClipVertex clip_vertices[RD_MAX_CLIP_VERTICES];
|
|
DWORD m_dwInterpolate;
|
|
int clip_vertices_used;
|
|
RDCOLOR4 clip_color;
|
|
RDCOLOR4 clip_specular;
|
|
|
|
// User defined clipping planes
|
|
RDVECTOR4 m_userClipPlanes[RD_MAX_USER_CLIPPLANES];
|
|
|
|
// User clip planes transformed
|
|
RDUSERCLIPPLANE m_xfmUserClipPlanes[RD_MAX_USER_CLIPPLANES];
|
|
|
|
//---------------------------------------------------
|
|
// Methods
|
|
//---------------------------------------------------
|
|
HRESULT UpdateViewData();
|
|
void MakeClipVertexFromVertex( RDClipVertex& cv, RDVertex& v,
|
|
DWORD dwClipMask);
|
|
inline BOOL UseGuardBand() { return m_bUseGB; }
|
|
RDCLIPCODE ComputeClipCodes(RDCLIPCODE* pclipIntersection,
|
|
RDCLIPCODE* pclipUnion, FLOAT x_clip,
|
|
FLOAT y_clip, FLOAT z_clip, FLOAT w_clip);
|
|
void ComputeClipCodesTL( RDVertex* pVtx );
|
|
void Interpolate( RDClipVertex *out, RDClipVertex *p1, RDClipVertex *p2,
|
|
int code, D3DVALUE num, D3DVALUE denom );
|
|
int ClipByPlane( RDClipVertex **inv, RDClipVertex **outv, RDVECTOR4 *plane,
|
|
DWORD dwClipFlag, int count );
|
|
int ClipLineByPlane( RDCLIPTRIANGLE *line, RDVECTOR4 *plane,
|
|
DWORD dwClipBit);
|
|
void ComputeScreenCoordinates( RDClipVertex **inv, int count );
|
|
DWORD ComputeClipCodeGB( RDClipVertex *p );
|
|
DWORD ComputeClipCode( RDClipVertex *p );
|
|
#if 0
|
|
DWORD ComputeClipCodeUserPlanes( RDUSERCLIPPLANE *UserPlanes,
|
|
RDClipVertex *p);
|
|
#endif
|
|
int ClipLeft( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipRight( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipTop( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipBottom( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipFront( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipBack( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipLeftGB( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipRightGB( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipTopGB( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
int ClipBottomGB( RDClipVertex **inv, RDClipVertex **outv, int count);
|
|
|
|
int ClipLineLeft( RDCLIPTRIANGLE *inv);
|
|
int ClipLineRight( RDCLIPTRIANGLE *inv);
|
|
int ClipLineTop( RDCLIPTRIANGLE *inv);
|
|
int ClipLineBottom( RDCLIPTRIANGLE *inv);
|
|
int ClipLineFront( RDCLIPTRIANGLE *inv);
|
|
int ClipLineBack( RDCLIPTRIANGLE *inv);
|
|
int ClipLineLeftGB( RDCLIPTRIANGLE *inv);
|
|
int ClipLineRightGB( RDCLIPTRIANGLE *inv);
|
|
int ClipLineTopGB( RDCLIPTRIANGLE *inv);
|
|
int ClipLineBottomGB( RDCLIPTRIANGLE *inv);
|
|
|
|
int ClipSingleLine( RDCLIPTRIANGLE *line );
|
|
int ClipSingleTriangle( RDCLIPTRIANGLE *tri,
|
|
RDClipVertex ***clipVertexPointer );
|
|
|
|
void DrawPoint( RDVertex* pvV0 );
|
|
void DrawLine( RDVertex* pvV0, RDVertex* pvV1 );
|
|
void DrawTriangle( RDVertex* pvV0, RDVertex* pvV1, RDVertex* pvV2,
|
|
WORD wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE );
|
|
|
|
HRESULT DrawOnePrimitive( GArrayT<RDVertex>& VtxArray,
|
|
DWORD dwStartVertex,
|
|
D3DPRIMITIVETYPE PrimType,
|
|
UINT cVertices );
|
|
HRESULT DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray,
|
|
int StartVertexIndex,
|
|
LPWORD pIndices,
|
|
DWORD StartIndex,
|
|
UINT cIndices,
|
|
D3DPRIMITIVETYPE PrimType );
|
|
HRESULT DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray,
|
|
int StartVertexIndex,
|
|
LPDWORD pIndices,
|
|
DWORD StartIndex,
|
|
UINT cIndices,
|
|
D3DPRIMITIVETYPE PrimType );
|
|
|
|
};
|
|
|
|
|
|
// RefVP::m_dwTLState flags
|
|
#define RDPV_DOLIGHTING 0x00000001
|
|
#define RDPV_DOCLIPPING 0x00000002
|
|
#define RDPV_DOFOG 0x00000004
|
|
#define RDPV_DOSPECULAR 0x00000008
|
|
#define RDPV_RANGEFOG 0x00000010
|
|
#define RDPV_NORMALIZENORMALS 0x00000020
|
|
#define RDPV_LOCALVIEWER 0x00000040
|
|
#define RDPV_DOCOMPUTEPOINTSIZE 0x00000080
|
|
#define RDPV_DOPOINTSCALE 0x00000100
|
|
#define RDPV_DOTEXXFORM 0x00000200
|
|
#define RDPV_DOTEXGEN 0x00000400
|
|
#define RDPV_NEEDEYEXYZ 0x00000800
|
|
#define RDPV_NEEDEYENORMAL 0x00001000
|
|
|
|
// ColorVertexFlags
|
|
#define RDPV_VERTEXDIFFUSENEEDED 0x00002000
|
|
#define RDPV_VERTEXSPECULARNEEDED 0x00004000
|
|
#define RDPV_COLORVERTEXAMB 0x00008000
|
|
#define RDPV_COLORVERTEXDIFF 0x00010000
|
|
#define RDPV_COLORVERTEXSPEC 0x00020000
|
|
#define RDPV_COLORVERTEXEMIS 0x00040000
|
|
#define RDPV_COLORVERTEXFLAGS (RDPV_VERTEXDIFFUSENEEDED | \
|
|
RDPV_VERTEXSPECULARNEEDED | \
|
|
RDPV_COLORVERTEXAMB | \
|
|
RDPV_COLORVERTEXDIFF | \
|
|
RDPV_COLORVERTEXSPEC | \
|
|
RDPV_COLORVERTEXEMIS )
|
|
#define RDPV_DOINDEXEDVERTEXBLEND 0x00100000
|
|
#define RDPV_DOPOSITIONTWEENING 0x00200000
|
|
#define RDPV_DONORMALTWEENING 0x00400000
|
|
|
|
|
|
// RefVP::m_dwDirtyFlags flags
|
|
#define RDPV_DIRTY_PROJXFM 0x00000001
|
|
#define RDPV_DIRTY_VIEWXFM 0x00000002
|
|
#define RDPV_DIRTY_WORLDXFM 0x00000004
|
|
#define RDPV_DIRTY_WORLD1XFM 0x00000008
|
|
#define RDPV_DIRTY_WORLD2XFM 0x00000010
|
|
#define RDPV_DIRTY_WORLD3XFM 0x00000020
|
|
#define RDPV_DIRTY_XFORM (RDPV_DIRTY_PROJXFM | \
|
|
RDPV_DIRTY_VIEWXFM | \
|
|
RDPV_DIRTY_WORLDXFM | \
|
|
RDPV_DIRTY_WORLD1XFM | \
|
|
RDPV_DIRTY_WORLD2XFM | \
|
|
RDPV_DIRTY_WORLD3XFM)
|
|
#define RDPV_DIRTY_MATERIAL 0x00000100
|
|
#define RDPV_DIRTY_SETLIGHT 0x00000200
|
|
#define RDPV_DIRTY_NEEDXFMLIGHT 0x00000400
|
|
#define RDPV_DIRTY_COLORVTX 0x00000800
|
|
#define RDPV_DIRTY_LIGHTING (RDPV_DIRTY_MATERIAL | \
|
|
RDPV_DIRTY_SETLIGHT | \
|
|
RDPV_DIRTY_NEEDXFMLIGHT | \
|
|
RDPV_DIRTY_COLORVTX)
|
|
#define RDPV_DIRTY_FOG 0x00010000
|
|
#define RDPV_DIRTY_INVERSEWORLDVIEW 0x00020000
|
|
|
|
//---------------------------------------------------------------------
|
|
// RDPTRSTRIDE: A class instanced once per vertex element.
|
|
//---------------------------------------------------------------------
|
|
class RDPTRSTRIDE
|
|
{
|
|
public:
|
|
RDPTRSTRIDE()
|
|
{
|
|
Null();
|
|
}
|
|
inline void Init( LPVOID pData, DWORD dwStride )
|
|
{
|
|
m_pData = m_pCurrent = pData;
|
|
m_dwStride = dwStride;
|
|
}
|
|
inline void Null()
|
|
{
|
|
memset( this, 0, sizeof( *this ) );
|
|
}
|
|
inline void SetStride( DWORD dwStride )
|
|
{
|
|
m_dwStride = dwStride;
|
|
}
|
|
inline DWORD GetStride()
|
|
{
|
|
return m_dwStride;
|
|
}
|
|
inline LPVOID GetFirst()
|
|
{
|
|
return m_pData;
|
|
}
|
|
inline LPVOID GetCurrent()
|
|
{
|
|
return m_pCurrent;
|
|
}
|
|
inline LPVOID Reset()
|
|
{
|
|
return (m_pCurrent = m_pData);
|
|
}
|
|
inline LPVOID Next()
|
|
{
|
|
m_pCurrent = (LPVOID)((LPBYTE)m_pCurrent + m_dwStride);
|
|
return m_pCurrent;
|
|
}
|
|
|
|
LPVOID operator []( DWORD dwIndex ) const
|
|
{
|
|
return (LPVOID)((LPBYTE)m_pData + dwIndex*m_dwStride);
|
|
}
|
|
|
|
|
|
protected:
|
|
LPVOID m_pData;
|
|
DWORD m_dwStride; // in number of bytes
|
|
LPVOID m_pCurrent;
|
|
DWORD m_dwCurrentIndex;
|
|
};
|
|
|
|
//---------------------------------------------------------------------
|
|
// Struct holding the shader ptr
|
|
//---------------------------------------------------------------------
|
|
struct RDVShaderHandle
|
|
{
|
|
RDVShaderHandle()
|
|
{
|
|
m_pShader = NULL;
|
|
#if DBG
|
|
m_tag = 0;
|
|
#endif
|
|
}
|
|
RDVShader* m_pShader;
|
|
#if DBG
|
|
// Non zero means that it has been allocated
|
|
DWORD m_tag;
|
|
#endif
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// Fixed function vertex processing pipeline object
|
|
//---------------------------------------------------------------------
|
|
class RefVP : public RDAlloc
|
|
{
|
|
protected:
|
|
|
|
// The pointer to the driver object to obtain state
|
|
RefDev* m_pDev;
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Unprocessed state set by the DDI
|
|
//-------------------------------------------------------------------------
|
|
// Growable Light array
|
|
GArrayT<RDLight> m_LightArray;
|
|
|
|
// Current material to use for lighting
|
|
D3DMATERIAL7 m_Material;
|
|
|
|
// Transformation state stored by the reference implementation
|
|
RDMATRIX m_xfmProj;
|
|
RDMATRIX m_xfmView;
|
|
RDMATRIX m_xfmWorld[RD_MAX_WORLD_MATRICES];
|
|
RDMATRIX m_xfmTex[D3DHAL_TSS_MAXSTAGES];
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Vertex Elements
|
|
//-------------------------------------------------------------------------
|
|
RDPTRSTRIDE m_position;
|
|
RDPTRSTRIDE m_position2;
|
|
RDPTRSTRIDE m_blendweights;
|
|
RDPTRSTRIDE m_blendindices;
|
|
RDPTRSTRIDE m_normal;
|
|
RDPTRSTRIDE m_normal2;
|
|
RDPTRSTRIDE m_specular;
|
|
RDPTRSTRIDE m_diffuse;
|
|
RDPTRSTRIDE m_pointsize;
|
|
RDPTRSTRIDE m_tex[8];
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Cached T&L related render-state info
|
|
//-------------------------------------------------------------------------
|
|
DWORD m_dwTLState; // RenderState related flags
|
|
DWORD m_dwDirtyFlags; // Dirty flags
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Transformation data
|
|
//-------------------------------------------------------------------------
|
|
|
|
// Current transformation matrix
|
|
RDMATRIX m_xfmCurrent[RD_MAX_WORLD_MATRICES]; // using WORLDi matrix
|
|
RDMATRIX m_xfmToEye[RD_MAX_WORLD_MATRICES]; // Transforms to camera
|
|
// space (Mworld*Mview)
|
|
RDMATRIX m_xfmToEyeInv[RD_MAX_WORLD_MATRICES]; // and its Inverse
|
|
BYTE m_WorldProcessed[RD_MAX_WORLD_MATRICES];
|
|
|
|
UINT64 m_qwFVFIn; // FVF of the input vertices
|
|
UINT64 m_qwFVFOut; // FVF of the output vertices
|
|
|
|
int m_numVertexBlends;
|
|
RDTRANSFORMDATA m_TransformData;
|
|
|
|
FLOAT m_fPointSize;
|
|
FLOAT m_fPointAttA;
|
|
FLOAT m_fPointAttB;
|
|
FLOAT m_fPointAttC;
|
|
FLOAT m_fPointSizeMin;
|
|
FLOAT m_fPointSizeMax;
|
|
|
|
FLOAT m_fTweenFactor;
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Lighting data
|
|
//-------------------------------------------------------------------------
|
|
RDLIGHTVERTEX_FUNC_TABLE m_LightVertexTable;
|
|
RDLIGHTINGDATA m_lighting; // Lighting state
|
|
|
|
DWORD m_dwNumActiveTextureStages;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Methods
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT UpdateXformData();
|
|
void UpdateWorld( DWORD i );
|
|
HRESULT UpdateLightingData();
|
|
HRESULT UpdateFogData();
|
|
RDCLIPCODE ProcessVertices( UINT64 outFVF, GArrayT<RDVertex>& VtxArray,
|
|
DWORD count );
|
|
void LightVertex( RDLIGHTINGELEMENT *le );
|
|
void FogVertex ( RDVertex& Vout, RDVECTOR3 &v, RDLIGHTINGELEMENT *le,
|
|
int numVertexBlends, float *pBlendFactors,
|
|
BOOL bVertexInEyeSpace );
|
|
|
|
public:
|
|
RefVP();
|
|
|
|
inline void LightEnable( DWORD dwIndex, BOOL bEnable )
|
|
{
|
|
if( bEnable )
|
|
{
|
|
m_LightArray[dwIndex].Enable(&m_lighting.pActiveLights);
|
|
m_dwDirtyFlags |= RDPV_DIRTY_SETLIGHT;
|
|
}
|
|
else
|
|
{
|
|
m_LightArray[dwIndex].Disable(&m_lighting.pActiveLights);
|
|
}
|
|
}
|
|
|
|
inline HRESULT SetLightData( DWORD dwIndex, D3DLIGHT7* pData )
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HR_RET(m_LightArray[dwIndex].SetLight(pData));
|
|
m_dwDirtyFlags |= RDPV_DIRTY_SETLIGHT;
|
|
return S_OK;
|
|
}
|
|
HRESULT GrowLightArray( DWORD dwIndex );
|
|
friend class RefDev;
|
|
};
|
|
|
|
// Vertex Lighting functions
|
|
void RDLV_Directional( RDLIGHTINGDATA&, D3DLIGHT7 *, RDLIGHTI *,
|
|
RDLIGHTINGELEMENT *, DWORD, UINT64 );
|
|
void RDLV_PointAndSpot( RDLIGHTINGDATA&, D3DLIGHT7 *, RDLIGHTI *,
|
|
RDLIGHTINGELEMENT *, DWORD, UINT64 );
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#endif // _REFTNL_HPP
|