Source code of Windows XP (NT5)
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
31 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (C) Microsoft Corporation, 1998.
  3. //
  4. // reftnl.hpp
  5. //
  6. // Direct3D Reference Transform and Lighting - Main Header File
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #ifndef _REFTNL_HPP
  10. #define _REFTNL_HPP
  11. #define RD_GB_LEFT -32768.f
  12. #define RD_GB_TOP -32768.f
  13. #define RD_GB_RIGHT 32767.f
  14. #define RD_GB_BOTTOM 32767.f
  15. //-----------------------------------------------------------------------------
  16. //
  17. // Constants
  18. //
  19. //-----------------------------------------------------------------------------
  20. // Default color values that should be used when ther is no lighting and
  21. // color in vertices provided
  22. const DWORD RD_DEFAULT_DIFFUSE = 0xFFFFFFFF;
  23. const DWORD RD_DEFAULT_SPECULAR = 0;
  24. const DWORD RD_MAX_FVF_TEXCOORD = 8;
  25. const DWORD RD_MAX_VERTEX_COUNT = 2048;
  26. // Number of clipping planes
  27. const DWORD RD_MAX_USER_CLIPPLANES = 6;
  28. // Number of clipping planes
  29. const DWORD RD_MAX_CLIPPING_PLANES = (6+RD_MAX_USER_CLIPPLANES);
  30. // Number of blend weights
  31. const DWORD RD_MAX_BLEND_WEIGHTS = 4;
  32. // Number of world matrices
  33. const DWORD RD_MAX_WORLD_MATRICES = 256;
  34. const DWORD RD_WORLDMATRIXBASE = 256;
  35. // Space for vertices generated/copied while clipping one triangle
  36. const DWORD RD_MAX_CLIP_VERTICES = (( 2 * RD_MAX_CLIPPING_PLANES ) + 3 );
  37. // 3 verts. -> 1 tri, 4 v -> 2 t, N vertices -> (N - 2) triangles
  38. const DWORD RD_MAX_CLIP_TRIANGLES = ( RD_MAX_CLIP_VERTICES - 2 );
  39. // make smaller than guard band for easier clipping
  40. const float RD_MAX_POINT_SIZE = 64;
  41. //-----------------------------------------------------------------------------
  42. //
  43. // Forward defines
  44. //
  45. //-----------------------------------------------------------------------------
  46. class RDLight;
  47. //-----------------------------------------------------------------------------
  48. //
  49. // Typedefs
  50. //
  51. //-----------------------------------------------------------------------------
  52. typedef DWORD RDCLIPCODE;
  53. typedef D3DMATRIX RDMATRIX;
  54. //-----------------------------------------------------------------------------
  55. //
  56. // RDVertex - Internal vertex structure of the refrast. This is the
  57. // structure exchanged between the T&L and Rasterization parts
  58. // of the refrast.
  59. //
  60. //-----------------------------------------------------------------------------
  61. class RDVertex
  62. {
  63. public:
  64. RDVertex()
  65. {
  66. Init();
  67. }
  68. RDVertex( LPDWORD pVtx, DWORD dwFvf )
  69. {
  70. SetFvfData( pVtx, (UINT64)dwFvf );
  71. }
  72. RDVertex( LPDWORD pVtx, UINT64 qwFvf )
  73. {
  74. SetFvfData( pVtx, qwFvf );
  75. }
  76. RDCLIPCODE m_clip;
  77. FLOAT m_clip_x;
  78. FLOAT m_clip_y;
  79. FLOAT m_clip_z;
  80. FLOAT m_clip_w;
  81. RDVECTOR3 m_pos; // This is screen coordinates
  82. FLOAT m_rhw;
  83. RDCOLOR4 m_diffuse; // ARGB (0..1 each component)
  84. RDCOLOR4 m_specular; // ARGB
  85. FLOAT m_fog; // 0..1
  86. FLOAT m_pointsize;
  87. RDVECTOR4 m_tex[8];
  88. UINT64 m_qwFVF;
  89. void Init()
  90. {
  91. m_clip = 0;
  92. m_clip_x = m_clip_y = m_clip_z = m_clip_w = 0.0f;
  93. m_rhw = 0.0f;
  94. m_diffuse.a = m_diffuse.r = m_diffuse.g = m_diffuse.b = 1.0f;
  95. m_specular.a = m_specular.r = m_specular.g = m_specular.b = 0.0f;
  96. m_fog = 0.0f;
  97. m_pointsize = 1.0f;
  98. // Initialize texture coordinates to {0.0, 0.0, 0.0, 1.0}
  99. memset( m_tex, 0, sizeof(m_tex) );
  100. for( int i=0; i<8; i++ ) m_tex[i].w = 1.0f;
  101. m_qwFVF = 0;
  102. }
  103. void SetFVF( UINT64 qwControl )
  104. {
  105. m_qwFVF = qwControl;
  106. }
  107. void SetFvfData( LPDWORD pVtx, UINT64 qwFVF )
  108. {
  109. DWORD cDWORD = 0;
  110. Init();
  111. m_qwFVF = qwFVF;
  112. switch( qwFVF & D3DFVF_POSITION_MASK )
  113. {
  114. case D3DFVF_XYZRHW:
  115. memcpy( &m_pos, pVtx, 3*sizeof( float ) );
  116. pVtx += 3;
  117. m_rhw = *(float *)(pVtx);
  118. pVtx += 1;
  119. break;
  120. default:
  121. _ASSERT( TRUE, "RDVertex can only hold Transformed Vertices" );
  122. return;
  123. }
  124. if (qwFVF & D3DFVF_PSIZE)
  125. {
  126. m_pointsize = *(FLOAT*)pVtx;
  127. pVtx++;
  128. }
  129. if (qwFVF & D3DFVF_DIFFUSE)
  130. {
  131. MakeRDCOLOR4( &m_diffuse, *pVtx );
  132. pVtx++;
  133. }
  134. if (qwFVF & D3DFVF_SPECULAR)
  135. {
  136. MakeRDCOLOR4( &m_specular, *pVtx );
  137. m_fog = m_specular.a;
  138. m_qwFVF |= D3DFVFP_FOG;
  139. pVtx++;
  140. }
  141. if (qwFVF & D3DFVF_FOG)
  142. {
  143. m_fog = *(FLOAT*)pVtx;
  144. m_qwFVF |= D3DFVFP_FOG;
  145. pVtx++;
  146. }
  147. DWORD dwNumTexCoord = (DWORD)(FVF_TEXCOORD_NUMBER(qwFVF));
  148. DWORD dwTextureFormats = (DWORD)qwFVF >> 16;
  149. // Texture formats size 00 01 10 11
  150. static DWORD dwTextureSize[4] = {2, 3, 4, 1};
  151. for (DWORD i=0; i < dwNumTexCoord; i++)
  152. {
  153. memcpy( &m_tex[i], pVtx,
  154. sizeof( float )*dwTextureSize[dwTextureFormats & 3] );
  155. pVtx += dwTextureSize[dwTextureFormats & 3];
  156. dwTextureFormats >>= 2;
  157. }
  158. }
  159. FLOAT GetRHW( void ) const
  160. {
  161. return ( m_qwFVF & D3DFVF_XYZRHW ) ? m_rhw : 1.f ;
  162. }
  163. FLOAT* GetPtrXYZ( void ) { return (FLOAT*)&m_pos; }
  164. FLOAT GetX( void ) const { return m_pos.x; }
  165. FLOAT GetY( void ) const { return m_pos.y; }
  166. FLOAT GetZ( void ) const { return m_pos.z; }
  167. DWORD GetDiffuse( void ) const
  168. {
  169. DWORD diff =
  170. D3DRGBA(m_diffuse.r, m_diffuse.g, m_diffuse.b, m_diffuse.a);
  171. // return color if available else white (default)
  172. return ( m_qwFVF & D3DFVF_DIFFUSE ) ? diff : 0xffffffff;
  173. }
  174. DWORD GetSpecular( void ) const
  175. {
  176. DWORD spec =
  177. D3DRGBA(m_specular.r, m_specular.g, m_specular.b, m_specular.a);
  178. // return color if available else black (default)
  179. return ( m_qwFVF & D3DFVF_SPECULAR ) ? spec : 0x00000000;
  180. }
  181. UINT TexCrdCount( void ) const
  182. {
  183. return
  184. (UINT)(( m_qwFVF & D3DFVF_TEXCOUNT_MASK ) >> D3DFVF_TEXCOUNT_SHIFT);
  185. }
  186. FLOAT GetTexCrd( UINT iCrd, UINT iCrdSet ) const
  187. {
  188. // This function ensures that right defaults are returned.
  189. // Note, except for the q coordinate (which defaults to 1.0)
  190. // the rest are 0.0.
  191. if( (iCrdSet < TexCrdCount()) &&
  192. (iCrd < GetTexCoordDim(m_qwFVF, iCrdSet)) )
  193. {
  194. return *( (FLOAT*)&m_tex[iCrdSet] + iCrd );
  195. }
  196. else if( iCrd == 3 )
  197. {
  198. return 1.0f;
  199. }
  200. else
  201. {
  202. return 0.0f;
  203. }
  204. }
  205. FLOAT GetLastTexCrd( UINT iCrdSet ) const
  206. {
  207. // Return the last texture coordinate if present else 1.0
  208. if( iCrdSet < TexCrdCount() )
  209. {
  210. return *( (FLOAT*)&m_tex[iCrdSet] +
  211. GetTexCoordDim(m_qwFVF, iCrdSet) - 1);
  212. }
  213. else
  214. {
  215. return 1.0f;
  216. }
  217. }
  218. FLOAT GetPointSize( void ) const
  219. {
  220. return ( m_qwFVF & D3DFVF_PSIZE ) ? m_pointsize : 1.0f;
  221. }
  222. FLOAT GetFog( void ) const
  223. {
  224. return ( m_qwFVF & D3DFVFP_FOG ) ? m_fog : 0.0f;
  225. }
  226. };
  227. class RDClipVertex : public RDVertex
  228. {
  229. public:
  230. RDClipVertex()
  231. {
  232. next = NULL;
  233. }
  234. RDClipVertex *next;
  235. };
  236. struct RDCLIPTRIANGLE
  237. {
  238. RDCLIPTRIANGLE()
  239. {
  240. memset( this, 0, sizeof(*this) );
  241. }
  242. RDClipVertex *v[3];
  243. };
  244. struct RDUSERCLIPPLANE
  245. {
  246. RDUSERCLIPPLANE()
  247. {
  248. memset( this, 0, sizeof(*this) );
  249. }
  250. RDVECTOR4 plane;
  251. BOOL bActive;
  252. };
  253. //-----------------------------------------------------------------------------
  254. //
  255. // RDTRANSFORMDATA - Transformation data used by Refrence T&L implementation
  256. // to transform vertices.
  257. //
  258. //-----------------------------------------------------------------------------
  259. struct RDTRANSFORMDATA
  260. {
  261. RDTRANSFORMDATA()
  262. {
  263. memset( this, 0, sizeof(*this) );
  264. }
  265. RDMATRIX m_PS; // Mproj * Mshift
  266. RDMATRIX m_VPS; // Mview * PS
  267. RDMATRIX m_VPSInv; // Inverse( Mview * PS )
  268. RDMATRIX m_CTMI; // Inverse current transformation matrix
  269. RDVECTOR4 m_frustum[6]; // Normalized plane equations for viewing
  270. // frustum in the model space
  271. DWORD m_dwFlags;
  272. };
  273. //---------------------------------------------------------------------
  274. // RDLIGHTINGDATA
  275. // All the lighting related state clubbed together
  276. //---------------------------------------------------------------------
  277. struct RDLIGHTINGDATA
  278. {
  279. RDLIGHTINGDATA()
  280. {
  281. memset( this, 0, sizeof(*this) );
  282. }
  283. // Active Light list
  284. RDLight *pActiveLights;
  285. // Temporary data used when computing lighting
  286. RDVECTOR3 eye_in_eye; // eye position in eye space
  287. // It is (0, 0, 0)
  288. // Ma * La + Me (Ambient and Emissive) ------
  289. RDCOLOR3 ambEmiss;
  290. // ColorVertex stuff ------------------------
  291. RDCOLOR3 *pAmbientSrc;
  292. RDCOLOR3 *pDiffuseSrc;
  293. RDCOLOR3 *pSpecularSrc;
  294. RDCOLOR3 *pEmissiveSrc;
  295. // Diffuse ----------------------------------
  296. RDCOLOR3 vertexDiffuse; // Provided with a vertex, used if
  297. // COLORVERTEX is enabled and a diffuse
  298. // color is provided in the vertex
  299. RDCOLOR3 diffuse; // Diffuse accumulates here
  300. DWORD outDiffuse; // Diffuse color result of lighting
  301. // Specular --------------------------------
  302. RDCOLOR3 vertexSpecular;// Provided with a vertex, used if
  303. // COLORVERTEX is enabled and a specular
  304. // color is provided in the vertex
  305. RDCOLOR3 specular; // Specular accumulates here
  306. DWORD outSpecular; // Specular color result of lighting
  307. D3DVALUE specThreshold; // If the dot product is less than this
  308. // value, specular factor is zero
  309. // End of temporary data
  310. // RENDERSTATEAMBIENT --------------------------------------
  311. // Ambient color set by D3DRENDERSTATE_AMBIENT
  312. // They are all scaled to 0 - 1
  313. D3DVALUE ambient_red;
  314. D3DVALUE ambient_green;
  315. D3DVALUE ambient_blue;
  316. DWORD ambient_save; // Original unscaled color
  317. // Fog -----------------------------------------------------
  318. int fog_mode;
  319. D3DCOLOR fog_color;
  320. D3DVALUE fog_density;
  321. D3DVALUE fog_start;
  322. D3DVALUE fog_end;
  323. D3DVALUE fog_factor; // 255 / (fog_end - fog_start)
  324. D3DCOLORMODEL color_model;
  325. // Material ------------------------------------------------
  326. // For color material
  327. LPDWORD pDiffuseAlphaSrc;
  328. LPDWORD pSpecularAlphaSrc;
  329. DWORD materialDiffAlpha; // Current material diffuse
  330. // alpha (0-255) shifted left
  331. // by 24 bits
  332. DWORD materialSpecAlpha; // Current material specular
  333. // alpha (0-255) shifted left
  334. // by 24 bits
  335. DWORD vertexDiffAlpha; // Current material diffuse
  336. // alpha (0-255) shifted left
  337. // by 24 bits
  338. DWORD vertexSpecAlpha; // Current material specular
  339. // alpha (0-255) shifted left
  340. // by 24 bits
  341. D3DMATERIAL7 material; // Cached material data
  342. RDCOLOR3 matAmb;
  343. RDCOLOR3 matDiff;
  344. RDCOLOR3 matSpec;
  345. RDCOLOR3 matEmis;
  346. };
  347. //-----------------------------------------------------------------------------
  348. //
  349. // RDLight - The light object used by the Reference T&L implementation
  350. // An array of these are instanced in the RefDev object.
  351. //
  352. //-----------------------------------------------------------------------------
  353. struct RDLIGHTI
  354. {
  355. RDLIGHTI()
  356. {
  357. memset( this, 0, sizeof(*this) );
  358. }
  359. DWORD flags;
  360. RDVECTOR3 position_in_eye; // In the eye space
  361. RDVECTOR3 direction_in_eye; // In the eye space
  362. //
  363. // Saved light colors scaled from 0 - 255, needed for COLORVERTEX
  364. //
  365. D3DCOLORVALUE La; // light ambient
  366. D3DCOLORVALUE Ld; // light diffuse
  367. D3DCOLORVALUE Ls; // light specular
  368. //
  369. // Precomputed colors scaled from 0 - 255,
  370. //
  371. D3DCOLORVALUE Ma_La; // Material ambient times light ambient
  372. D3DCOLORVALUE Md_Ld; // Material diffuse times light diffuse
  373. D3DCOLORVALUE Ms_Ls; // Material specular times light specular
  374. RDVECTOR3 halfway;
  375. // Stuff for SpotLights
  376. D3DVALUE range_squared;
  377. D3DVALUE cos_theta_by_2;
  378. D3DVALUE cos_phi_by_2;
  379. D3DVALUE inv_theta_minus_phi;
  380. };
  381. //-----------------------------------------------------------------------------
  382. // Function pointer to the functions that light a vertex
  383. //-----------------------------------------------------------------------------
  384. typedef void (*RDLIGHTVERTEXFN)( RDLIGHTINGDATA& LData, D3DLIGHT7 *pLight,
  385. RDLIGHTI *pLightI, RDLIGHTINGELEMENT *in,
  386. DWORD dwFlags, UINT64 qwFVFIn );
  387. //-----------------------------------------------------------------------------
  388. // Functions to compute lighting
  389. //-----------------------------------------------------------------------------
  390. struct RDLIGHTVERTEX_FUNC_TABLE
  391. {
  392. RDLIGHTVERTEX_FUNC_TABLE()
  393. {
  394. memset( this, 0, sizeof(*this) );
  395. }
  396. RDLIGHTVERTEXFN pfnDirectional;
  397. RDLIGHTVERTEXFN pfnParallelPoint;
  398. RDLIGHTVERTEXFN pfnSpot;
  399. RDLIGHTVERTEXFN pfnPoint;
  400. };
  401. //-----------------------------------------------------------------------------
  402. //
  403. // RDLight - The light object used by the Reference T&L implementation
  404. // An array of these are instanced in the RefDev object.
  405. //
  406. //-----------------------------------------------------------------------------
  407. #define RDLIGHT_ENABLED 0x00000001 // Is the light active
  408. #define RDLIGHT_NEEDSPROCESSING 0x00000002 // Is the light data processed
  409. #define RDLIGHT_REFERED 0x00000004 // Has the light been refered
  410. // to
  411. class RDLight : public RDAlloc
  412. {
  413. public:
  414. RDLight();
  415. BOOL IsEnabled() {return (m_dwFlags & RDLIGHT_ENABLED);}
  416. BOOL NeedsProcessing() {return (m_dwFlags & RDLIGHT_NEEDSPROCESSING);}
  417. BOOL IsRefered() { return (m_dwFlags & RDLIGHT_REFERED); }
  418. HRESULT SetLight(LPD3DLIGHT7 pLight);
  419. HRESULT GetLight( LPD3DLIGHT7 pLight );
  420. void ProcessLight( D3DMATERIAL7 *mat, RDLIGHTVERTEX_FUNC_TABLE *pTbl);
  421. void XformLight( D3DMATRIX* mV );
  422. void Enable( RDLight **ppRoot );
  423. void Disable( RDLight **ppRoot );
  424. private:
  425. // Flags
  426. DWORD m_dwFlags;
  427. // Active List next element
  428. RDLight *m_Next;
  429. // Specific function to light the vertex
  430. RDLIGHTVERTEXFN m_pfnLightVertex;
  431. // Light data set by the runtime
  432. D3DLIGHT7 m_Light;
  433. // Light data computed by the driver
  434. RDLIGHTI m_LightI;
  435. friend class RefDev;
  436. friend class RefVP;
  437. };
  438. //---------------------------------------------------------------------
  439. //
  440. // The clipper object. Contains digested Viewport information
  441. // calculated from viewport settings.
  442. //
  443. //---------------------------------------------------------------------
  444. class RefClipper
  445. {
  446. public:
  447. RefClipper();
  448. // The pointer to the driver object to obtain state
  449. RefDev* m_pDev;
  450. // m_dwDirtyFlags
  451. static const DWORD RCLIP_DIRTY_ZRANGE;
  452. static const DWORD RCLIP_DIRTY_VIEWRECT;
  453. static const DWORD RCLIP_DO_FLATSHADING;
  454. static const DWORD RCLIP_DO_WIREFRAME;
  455. static const DWORD RCLIP_DO_ADJUSTWRAP;
  456. static const DWORD RCLIP_Z_ENABLE;
  457. DWORD m_dwFlags;
  458. // Viewport data from the DDI.
  459. D3DVIEWPORT7 m_Viewport;
  460. // Is it guardband or not ?
  461. BOOL m_bUseGB;
  462. D3DVALUE dvX; // dwX
  463. D3DVALUE dvY; // dwY
  464. D3DVALUE dvWidth; // dwWidth
  465. D3DVALUE dvHeight; // dwHeight
  466. // Coefficients to compute screen coordinates from normalized window
  467. // coordinates
  468. D3DVALUE scaleX; // dvWidth/2
  469. D3DVALUE scaleY; // dvHeight/2
  470. D3DVALUE scaleZ; // (Viewport->dvMaxZ - Viewport->dvMinZ)
  471. D3DVALUE offsetX; // dvX + scaleX
  472. D3DVALUE offsetY; // dvY + scaleY
  473. D3DVALUE offsetZ; // Viewport->dvMinZ
  474. // Coefficients to compute screen coordinates from normalized window
  475. // coordinates
  476. D3DVALUE scaleXi; // Inverse of scaleX
  477. D3DVALUE scaleYi; // Inverse of scaleY
  478. D3DVALUE scaleZi; // Inverse of scaleZ
  479. // Min and max values for viewport window in pixels
  480. D3DVALUE minX; // offsetX - scaleX
  481. D3DVALUE minY; // offsetY - scaleY
  482. D3DVALUE maxX; // offsetX + scaleX
  483. D3DVALUE maxY; // offsetY + scaleY
  484. // Min and max window values with guard band in pixels
  485. D3DVALUE minXgb;
  486. D3DVALUE minYgb;
  487. D3DVALUE maxXgb;
  488. D3DVALUE maxYgb;
  489. // Coefficients to transform a vertex to perform the guard band clipping
  490. // x*gb11 + w*gb41
  491. // y*gb22 + w*gb42
  492. //
  493. D3DVALUE gb11;
  494. D3DVALUE gb22;
  495. D3DVALUE gb41;
  496. D3DVALUE gb42;
  497. // Coefficients to apply clipping rules for the guard band clipping
  498. // They are used by clipping routins
  499. // w*Kgbx1 < x < w*Kgbx2
  500. // w*Kgby1 < y < w*Kgby2
  501. //
  502. D3DVALUE Kgbx1;
  503. D3DVALUE Kgby1;
  504. D3DVALUE Kgbx2;
  505. D3DVALUE Kgby2;
  506. // Clipping related
  507. RDCLIPCODE m_clipUnion; // OR of all vertex clip flags
  508. RDCLIPCODE m_clipIntersection; // AND of all vertex clip flags
  509. GArrayT<RDVertex> ClipBuf;
  510. RDClipVertex *clip_vbuf1[RD_MAX_CLIP_VERTICES];
  511. RDClipVertex *clip_vbuf2[RD_MAX_CLIP_VERTICES];
  512. RDClipVertex **current_vbuf; // clip_vbuf1 or clip_vbuf2
  513. RDClipVertex clip_vertices[RD_MAX_CLIP_VERTICES];
  514. DWORD m_dwInterpolate;
  515. int clip_vertices_used;
  516. RDCOLOR4 clip_color;
  517. RDCOLOR4 clip_specular;
  518. // User defined clipping planes
  519. RDVECTOR4 m_userClipPlanes[RD_MAX_USER_CLIPPLANES];
  520. // User clip planes transformed
  521. RDUSERCLIPPLANE m_xfmUserClipPlanes[RD_MAX_USER_CLIPPLANES];
  522. //---------------------------------------------------
  523. // Methods
  524. //---------------------------------------------------
  525. HRESULT UpdateViewData();
  526. void MakeClipVertexFromVertex( RDClipVertex& cv, RDVertex& v,
  527. DWORD dwClipMask);
  528. inline BOOL UseGuardBand() { return m_bUseGB; }
  529. RDCLIPCODE ComputeClipCodes(RDCLIPCODE* pclipIntersection,
  530. RDCLIPCODE* pclipUnion, FLOAT x_clip,
  531. FLOAT y_clip, FLOAT z_clip, FLOAT w_clip);
  532. void ComputeClipCodesTL( RDVertex* pVtx );
  533. void Interpolate( RDClipVertex *out, RDClipVertex *p1, RDClipVertex *p2,
  534. int code, D3DVALUE num, D3DVALUE denom );
  535. int ClipByPlane( RDClipVertex **inv, RDClipVertex **outv, RDVECTOR4 *plane,
  536. DWORD dwClipFlag, int count );
  537. int ClipLineByPlane( RDCLIPTRIANGLE *line, RDVECTOR4 *plane,
  538. DWORD dwClipBit);
  539. void ComputeScreenCoordinates( RDClipVertex **inv, int count );
  540. DWORD ComputeClipCodeGB( RDClipVertex *p );
  541. DWORD ComputeClipCode( RDClipVertex *p );
  542. #if 0
  543. DWORD ComputeClipCodeUserPlanes( RDUSERCLIPPLANE *UserPlanes,
  544. RDClipVertex *p);
  545. #endif
  546. int ClipLeft( RDClipVertex **inv, RDClipVertex **outv, int count);
  547. int ClipRight( RDClipVertex **inv, RDClipVertex **outv, int count);
  548. int ClipTop( RDClipVertex **inv, RDClipVertex **outv, int count);
  549. int ClipBottom( RDClipVertex **inv, RDClipVertex **outv, int count);
  550. int ClipFront( RDClipVertex **inv, RDClipVertex **outv, int count);
  551. int ClipBack( RDClipVertex **inv, RDClipVertex **outv, int count);
  552. int ClipLeftGB( RDClipVertex **inv, RDClipVertex **outv, int count);
  553. int ClipRightGB( RDClipVertex **inv, RDClipVertex **outv, int count);
  554. int ClipTopGB( RDClipVertex **inv, RDClipVertex **outv, int count);
  555. int ClipBottomGB( RDClipVertex **inv, RDClipVertex **outv, int count);
  556. int ClipLineLeft( RDCLIPTRIANGLE *inv);
  557. int ClipLineRight( RDCLIPTRIANGLE *inv);
  558. int ClipLineTop( RDCLIPTRIANGLE *inv);
  559. int ClipLineBottom( RDCLIPTRIANGLE *inv);
  560. int ClipLineFront( RDCLIPTRIANGLE *inv);
  561. int ClipLineBack( RDCLIPTRIANGLE *inv);
  562. int ClipLineLeftGB( RDCLIPTRIANGLE *inv);
  563. int ClipLineRightGB( RDCLIPTRIANGLE *inv);
  564. int ClipLineTopGB( RDCLIPTRIANGLE *inv);
  565. int ClipLineBottomGB( RDCLIPTRIANGLE *inv);
  566. int ClipSingleLine( RDCLIPTRIANGLE *line );
  567. int ClipSingleTriangle( RDCLIPTRIANGLE *tri,
  568. RDClipVertex ***clipVertexPointer );
  569. void DrawPoint( RDVertex* pvV0 );
  570. void DrawLine( RDVertex* pvV0, RDVertex* pvV1 );
  571. void DrawTriangle( RDVertex* pvV0, RDVertex* pvV1, RDVertex* pvV2,
  572. WORD wFlags = D3DTRIFLAG_EDGEENABLETRIANGLE );
  573. HRESULT DrawOnePrimitive( GArrayT<RDVertex>& VtxArray,
  574. DWORD dwStartVertex,
  575. D3DPRIMITIVETYPE PrimType,
  576. UINT cVertices );
  577. HRESULT DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray,
  578. int StartVertexIndex,
  579. LPWORD pIndices,
  580. DWORD StartIndex,
  581. UINT cIndices,
  582. D3DPRIMITIVETYPE PrimType );
  583. HRESULT DrawOneIndexedPrimitive( GArrayT<RDVertex>& VtxArray,
  584. int StartVertexIndex,
  585. LPDWORD pIndices,
  586. DWORD StartIndex,
  587. UINT cIndices,
  588. D3DPRIMITIVETYPE PrimType );
  589. };
  590. // RefVP::m_dwTLState flags
  591. #define RDPV_DOLIGHTING 0x00000001
  592. #define RDPV_DOCLIPPING 0x00000002
  593. #define RDPV_DOFOG 0x00000004
  594. #define RDPV_DOSPECULAR 0x00000008
  595. #define RDPV_RANGEFOG 0x00000010
  596. #define RDPV_NORMALIZENORMALS 0x00000020
  597. #define RDPV_LOCALVIEWER 0x00000040
  598. #define RDPV_DOCOMPUTEPOINTSIZE 0x00000080
  599. #define RDPV_DOPOINTSCALE 0x00000100
  600. #define RDPV_DOTEXXFORM 0x00000200
  601. #define RDPV_DOTEXGEN 0x00000400
  602. #define RDPV_NEEDEYEXYZ 0x00000800
  603. #define RDPV_NEEDEYENORMAL 0x00001000
  604. // ColorVertexFlags
  605. #define RDPV_VERTEXDIFFUSENEEDED 0x00002000
  606. #define RDPV_VERTEXSPECULARNEEDED 0x00004000
  607. #define RDPV_COLORVERTEXAMB 0x00008000
  608. #define RDPV_COLORVERTEXDIFF 0x00010000
  609. #define RDPV_COLORVERTEXSPEC 0x00020000
  610. #define RDPV_COLORVERTEXEMIS 0x00040000
  611. #define RDPV_COLORVERTEXFLAGS (RDPV_VERTEXDIFFUSENEEDED | \
  612. RDPV_VERTEXSPECULARNEEDED | \
  613. RDPV_COLORVERTEXAMB | \
  614. RDPV_COLORVERTEXDIFF | \
  615. RDPV_COLORVERTEXSPEC | \
  616. RDPV_COLORVERTEXEMIS )
  617. #define RDPV_DOINDEXEDVERTEXBLEND 0x00100000
  618. #define RDPV_DOPOSITIONTWEENING 0x00200000
  619. #define RDPV_DONORMALTWEENING 0x00400000
  620. // RefVP::m_dwDirtyFlags flags
  621. #define RDPV_DIRTY_PROJXFM 0x00000001
  622. #define RDPV_DIRTY_VIEWXFM 0x00000002
  623. #define RDPV_DIRTY_WORLDXFM 0x00000004
  624. #define RDPV_DIRTY_WORLD1XFM 0x00000008
  625. #define RDPV_DIRTY_WORLD2XFM 0x00000010
  626. #define RDPV_DIRTY_WORLD3XFM 0x00000020
  627. #define RDPV_DIRTY_XFORM (RDPV_DIRTY_PROJXFM | \
  628. RDPV_DIRTY_VIEWXFM | \
  629. RDPV_DIRTY_WORLDXFM | \
  630. RDPV_DIRTY_WORLD1XFM | \
  631. RDPV_DIRTY_WORLD2XFM | \
  632. RDPV_DIRTY_WORLD3XFM)
  633. #define RDPV_DIRTY_MATERIAL 0x00000100
  634. #define RDPV_DIRTY_SETLIGHT 0x00000200
  635. #define RDPV_DIRTY_NEEDXFMLIGHT 0x00000400
  636. #define RDPV_DIRTY_COLORVTX 0x00000800
  637. #define RDPV_DIRTY_LIGHTING (RDPV_DIRTY_MATERIAL | \
  638. RDPV_DIRTY_SETLIGHT | \
  639. RDPV_DIRTY_NEEDXFMLIGHT | \
  640. RDPV_DIRTY_COLORVTX)
  641. #define RDPV_DIRTY_FOG 0x00010000
  642. #define RDPV_DIRTY_INVERSEWORLDVIEW 0x00020000
  643. //---------------------------------------------------------------------
  644. // RDPTRSTRIDE: A class instanced once per vertex element.
  645. //---------------------------------------------------------------------
  646. class RDPTRSTRIDE
  647. {
  648. public:
  649. RDPTRSTRIDE()
  650. {
  651. Null();
  652. }
  653. inline void Init( LPVOID pData, DWORD dwStride )
  654. {
  655. m_pData = m_pCurrent = pData;
  656. m_dwStride = dwStride;
  657. }
  658. inline void Null()
  659. {
  660. memset( this, 0, sizeof( *this ) );
  661. }
  662. inline void SetStride( DWORD dwStride )
  663. {
  664. m_dwStride = dwStride;
  665. }
  666. inline DWORD GetStride()
  667. {
  668. return m_dwStride;
  669. }
  670. inline LPVOID GetFirst()
  671. {
  672. return m_pData;
  673. }
  674. inline LPVOID GetCurrent()
  675. {
  676. return m_pCurrent;
  677. }
  678. inline LPVOID Reset()
  679. {
  680. return (m_pCurrent = m_pData);
  681. }
  682. inline LPVOID Next()
  683. {
  684. m_pCurrent = (LPVOID)((LPBYTE)m_pCurrent + m_dwStride);
  685. return m_pCurrent;
  686. }
  687. LPVOID operator []( DWORD dwIndex ) const
  688. {
  689. return (LPVOID)((LPBYTE)m_pData + dwIndex*m_dwStride);
  690. }
  691. protected:
  692. LPVOID m_pData;
  693. DWORD m_dwStride; // in number of bytes
  694. LPVOID m_pCurrent;
  695. DWORD m_dwCurrentIndex;
  696. };
  697. //---------------------------------------------------------------------
  698. // Struct holding the shader ptr
  699. //---------------------------------------------------------------------
  700. struct RDVShaderHandle
  701. {
  702. RDVShaderHandle()
  703. {
  704. m_pShader = NULL;
  705. #if DBG
  706. m_tag = 0;
  707. #endif
  708. }
  709. RDVShader* m_pShader;
  710. #if DBG
  711. // Non zero means that it has been allocated
  712. DWORD m_tag;
  713. #endif
  714. };
  715. //---------------------------------------------------------------------
  716. // Fixed function vertex processing pipeline object
  717. //---------------------------------------------------------------------
  718. class RefVP : public RDAlloc
  719. {
  720. protected:
  721. // The pointer to the driver object to obtain state
  722. RefDev* m_pDev;
  723. //-------------------------------------------------------------------------
  724. // Unprocessed state set by the DDI
  725. //-------------------------------------------------------------------------
  726. // Growable Light array
  727. GArrayT<RDLight> m_LightArray;
  728. // Current material to use for lighting
  729. D3DMATERIAL7 m_Material;
  730. // Transformation state stored by the reference implementation
  731. RDMATRIX m_xfmProj;
  732. RDMATRIX m_xfmView;
  733. RDMATRIX m_xfmWorld[RD_MAX_WORLD_MATRICES];
  734. RDMATRIX m_xfmTex[D3DHAL_TSS_MAXSTAGES];
  735. //-------------------------------------------------------------------------
  736. // Vertex Elements
  737. //-------------------------------------------------------------------------
  738. RDPTRSTRIDE m_position;
  739. RDPTRSTRIDE m_position2;
  740. RDPTRSTRIDE m_blendweights;
  741. RDPTRSTRIDE m_blendindices;
  742. RDPTRSTRIDE m_normal;
  743. RDPTRSTRIDE m_normal2;
  744. RDPTRSTRIDE m_specular;
  745. RDPTRSTRIDE m_diffuse;
  746. RDPTRSTRIDE m_pointsize;
  747. RDPTRSTRIDE m_tex[8];
  748. //-------------------------------------------------------------------------
  749. // Cached T&L related render-state info
  750. //-------------------------------------------------------------------------
  751. DWORD m_dwTLState; // RenderState related flags
  752. DWORD m_dwDirtyFlags; // Dirty flags
  753. //-------------------------------------------------------------------------
  754. // Transformation data
  755. //-------------------------------------------------------------------------
  756. // Current transformation matrix
  757. RDMATRIX m_xfmCurrent[RD_MAX_WORLD_MATRICES]; // using WORLDi matrix
  758. RDMATRIX m_xfmToEye[RD_MAX_WORLD_MATRICES]; // Transforms to camera
  759. // space (Mworld*Mview)
  760. RDMATRIX m_xfmToEyeInv[RD_MAX_WORLD_MATRICES]; // and its Inverse
  761. BYTE m_WorldProcessed[RD_MAX_WORLD_MATRICES];
  762. UINT64 m_qwFVFIn; // FVF of the input vertices
  763. UINT64 m_qwFVFOut; // FVF of the output vertices
  764. int m_numVertexBlends;
  765. RDTRANSFORMDATA m_TransformData;
  766. FLOAT m_fPointSize;
  767. FLOAT m_fPointAttA;
  768. FLOAT m_fPointAttB;
  769. FLOAT m_fPointAttC;
  770. FLOAT m_fPointSizeMin;
  771. FLOAT m_fPointSizeMax;
  772. FLOAT m_fTweenFactor;
  773. //-------------------------------------------------------------------------
  774. // Lighting data
  775. //-------------------------------------------------------------------------
  776. RDLIGHTVERTEX_FUNC_TABLE m_LightVertexTable;
  777. RDLIGHTINGDATA m_lighting; // Lighting state
  778. DWORD m_dwNumActiveTextureStages;
  779. ///////////////////////////////////////////////////////////////////////////
  780. // Methods
  781. ///////////////////////////////////////////////////////////////////////////
  782. HRESULT UpdateXformData();
  783. void UpdateWorld( DWORD i );
  784. HRESULT UpdateLightingData();
  785. HRESULT UpdateFogData();
  786. RDCLIPCODE ProcessVertices( UINT64 outFVF, GArrayT<RDVertex>& VtxArray,
  787. DWORD count );
  788. void LightVertex( RDLIGHTINGELEMENT *le );
  789. void FogVertex ( RDVertex& Vout, RDVECTOR3 &v, RDLIGHTINGELEMENT *le,
  790. int numVertexBlends, float *pBlendFactors,
  791. BOOL bVertexInEyeSpace );
  792. public:
  793. RefVP();
  794. inline void LightEnable( DWORD dwIndex, BOOL bEnable )
  795. {
  796. if( bEnable )
  797. {
  798. m_LightArray[dwIndex].Enable(&m_lighting.pActiveLights);
  799. m_dwDirtyFlags |= RDPV_DIRTY_SETLIGHT;
  800. }
  801. else
  802. {
  803. m_LightArray[dwIndex].Disable(&m_lighting.pActiveLights);
  804. }
  805. }
  806. inline HRESULT SetLightData( DWORD dwIndex, D3DLIGHT7* pData )
  807. {
  808. HRESULT hr = S_OK;
  809. HR_RET(m_LightArray[dwIndex].SetLight(pData));
  810. m_dwDirtyFlags |= RDPV_DIRTY_SETLIGHT;
  811. return S_OK;
  812. }
  813. HRESULT GrowLightArray( DWORD dwIndex );
  814. friend class RefDev;
  815. };
  816. // Vertex Lighting functions
  817. void RDLV_Directional( RDLIGHTINGDATA&, D3DLIGHT7 *, RDLIGHTI *,
  818. RDLIGHTINGELEMENT *, DWORD, UINT64 );
  819. void RDLV_PointAndSpot( RDLIGHTINGDATA&, D3DLIGHT7 *, RDLIGHTI *,
  820. RDLIGHTINGELEMENT *, DWORD, UINT64 );
  821. ///////////////////////////////////////////////////////////////////////////////
  822. #endif // _REFTNL_HPP