Leaked source code of windows server 2003
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.

3258 lines
132 KiB

  1. namespace RGB_RAST_LIB_NAMESPACE
  2. {
  3. // TODO: Clean-up
  4. inline D3DI_SPANTEX_FORMAT ConvPixelFormat( const DDPIXELFORMAT& DDPixFmt)
  5. {
  6. if((DDPixFmt.dwFlags& DDPF_ZBUFFER)!= 0)
  7. {
  8. switch(DDPixFmt.dwZBitMask)
  9. {
  10. case( 0x0000FFFF): return D3DI_SPTFMT_Z16S0;
  11. case( 0xFFFFFF00): return D3DI_SPTFMT_Z24S8;
  12. case( 0x0000FFFE): return D3DI_SPTFMT_Z15S1;
  13. case( 0xFFFFFFFF): return D3DI_SPTFMT_Z32S0;
  14. default: return D3DI_SPTFMT_NULL;
  15. }
  16. }
  17. else if((DDPixFmt.dwFlags& DDPF_BUMPDUDV)!= 0)
  18. {
  19. switch( DDPixFmt.dwBumpDvBitMask)
  20. {
  21. case( 0x0000ff00):
  22. switch( DDPixFmt.dwRGBBitCount)
  23. {
  24. case( 24): return D3DI_SPTFMT_U8V8L8;
  25. case( 16): return D3DI_SPTFMT_U8V8;
  26. default: return D3DI_SPTFMT_NULL;
  27. }
  28. break;
  29. case( 0x000003e0): return D3DI_SPTFMT_U5V5L6;
  30. default: return D3DI_SPTFMT_NULL;
  31. }
  32. }
  33. else if((DDPixFmt.dwFlags& DDPF_PALETTEINDEXED8)!= 0)
  34. return D3DI_SPTFMT_PALETTE8;
  35. else if((DDPixFmt.dwFlags& DDPF_PALETTEINDEXED4)!= 0)
  36. return D3DI_SPTFMT_PALETTE4;
  37. else if( DDPixFmt.dwFourCC== MAKEFOURCC('U', 'Y', 'V', 'Y'))
  38. return D3DI_SPTFMT_UYVY;
  39. else if( DDPixFmt.dwFourCC== MAKEFOURCC('Y', 'U', 'Y', '2'))
  40. return D3DI_SPTFMT_YUY2;
  41. else if( DDPixFmt.dwFourCC== MAKEFOURCC('D', 'X', 'T', '1'))
  42. return D3DI_SPTFMT_DXT1;
  43. else if( DDPixFmt.dwFourCC== MAKEFOURCC('D', 'X', 'T', '2'))
  44. return D3DI_SPTFMT_DXT2;
  45. else if( DDPixFmt.dwFourCC== MAKEFOURCC('D', 'X', 'T', '3'))
  46. return D3DI_SPTFMT_DXT3;
  47. else if( DDPixFmt.dwFourCC== MAKEFOURCC('D', 'X', 'T', '4'))
  48. return D3DI_SPTFMT_DXT4;
  49. else if( DDPixFmt.dwFourCC== MAKEFOURCC('D', 'X', 'T', '5'))
  50. return D3DI_SPTFMT_DXT5;
  51. else
  52. {
  53. UINT uFmt = DDPixFmt.dwGBitMask | DDPixFmt.dwRBitMask;
  54. if (DDPixFmt.dwFlags & DDPF_ALPHAPIXELS)
  55. {
  56. uFmt |= DDPixFmt.dwRGBAlphaBitMask;
  57. }
  58. switch (uFmt)
  59. {
  60. case 0x00ffff00:
  61. switch (DDPixFmt.dwRGBBitCount)
  62. {
  63. case 32: return D3DI_SPTFMT_B8G8R8X8;
  64. case 24: return D3DI_SPTFMT_B8G8R8;
  65. default: return D3DI_SPTFMT_NULL;
  66. }
  67. break;
  68. case 0xffffff00:
  69. return D3DI_SPTFMT_B8G8R8A8;
  70. case 0xffe0:
  71. if (DDPixFmt.dwFlags & DDPF_ALPHAPIXELS)
  72. return D3DI_SPTFMT_B5G5R5A1;
  73. else
  74. return D3DI_SPTFMT_B5G6R5;
  75. case 0x07fe0: return D3DI_SPTFMT_B5G5R5;
  76. case 0xff0: return D3DI_SPTFMT_B4G4R4;
  77. case 0xfff0: return D3DI_SPTFMT_B4G4R4A4;
  78. case 0xff: return D3DI_SPTFMT_L8;
  79. case 0xffff: return D3DI_SPTFMT_L8A8;
  80. case 0xfc: return D3DI_SPTFMT_B2G3R3;
  81. default: return D3DI_SPTFMT_NULL;
  82. }
  83. }
  84. return D3DI_SPTFMT_NULL;
  85. }
  86. // Records the stride and the member offsets of the current FVF vertex type
  87. // Used to pack a FVF vertex into one known by the rasterizer, such as
  88. // RAST_GENERIC_VERTEX
  89. typedef struct _FVFDATA
  90. {
  91. // 0 means no according field
  92. INT16 offsetRHW;
  93. INT16 offsetPSize;
  94. INT16 offsetDiff;
  95. INT16 offsetSpec;
  96. INT16 offsetTex[D3DHAL_TSS_MAXSTAGES];
  97. UINT16 stride;
  98. RAST_VERTEX_TYPE vtxType;
  99. DWORD preFVF;
  100. INT TexIdx[D3DHAL_TSS_MAXSTAGES];
  101. UINT cActTex;
  102. }FVFDATA;
  103. class CRGBStateSet:
  104. public CSubStateSet< CRGBStateSet, CRGBContext>
  105. {
  106. public:
  107. CRGBStateSet( CRGBContext& C, const D3DHAL_DP2COMMAND* pBeginSS, const
  108. D3DHAL_DP2COMMAND* pEndSS): CSubStateSet< CRGBStateSet, CRGBContext>(
  109. C, pBeginSS, pEndSS)
  110. { }
  111. ~CRGBStateSet()
  112. { }
  113. };
  114. typedef CStdDrawPrimitives2< CRGBContext, CRGBStateSet,
  115. static_hash_map< DWORD, CRGBStateSet, 32> > TDrawPrimitives2;
  116. typedef CSubContext< CRGBContext, CRGBDriver::TPerDDrawData,
  117. CRTarget< CRGBDriver::TSurface*, CRGBDriver::TPerDDrawData::TSurfDBEntry*> >
  118. TSubContext;
  119. class CRGBContext:
  120. public TSubContext,
  121. public TDrawPrimitives2,
  122. public CStdDP2SetVertexShaderStore< CRGBContext>,
  123. public CStdDP2WInfoStore< CRGBContext>,
  124. public CStdDP2RenderStateStore< CRGBContext>,
  125. public CStdDP2TextureStageStateStore< CRGBContext>,
  126. public CStdDP2VStreamManager< CRGBContext, CVStream< CRGBDriver::TSurface*,
  127. CRGBDriver::TPerDDrawData::TSurfDBEntry*> >,
  128. public CStdDP2IStreamManager< CRGBContext, CIStream< CRGBDriver::TSurface*,
  129. CRGBDriver::TPerDDrawData::TSurfDBEntry*> >,
  130. public CStdDP2PaletteManager< CRGBContext, CPalDBEntry,
  131. static_hash_map< DWORD, CPalDBEntry, 4> >
  132. {
  133. public: // Types
  134. typedef TPerDDrawData::TDriver::TSurface TSurface;
  135. protected: // Types
  136. typedef block< TDP2CmdBind, 17> TDP2Bindings;
  137. typedef block< TRecDP2CmdBind, 7> TRecDP2Bindings;
  138. struct SHandleHasCaps: public unary_function< DWORD, bool>
  139. {
  140. const TPerDDrawData& m_PDDD;
  141. DWORD m_dwCaps;
  142. explicit SHandleHasCaps( const TPerDDrawData& PDDD, const DWORD dwCaps)
  143. throw(): m_PDDD( PDDD), m_dwCaps( dwCaps) { }
  144. result_type operator()( const argument_type Arg) const
  145. {
  146. const TPerDDrawData::TSurfDBEntry* pSurfDBEntry=
  147. m_PDDD.GetSurfDBEntry( Arg);
  148. assert( pSurfDBEntry!= NULL);
  149. return((pSurfDBEntry->GetLCLddsCaps().dwCaps& m_dwCaps)== m_dwCaps);
  150. }
  151. };
  152. protected:
  153. static const TDP2Bindings c_DP2Bindings;
  154. static const TRecDP2Bindings c_RecDP2Bindings;
  155. D3DI_RASTCTX m_RastCtx;
  156. PrimProcessor m_PrimProc;
  157. D3DI_SPANTEX m_aSpanTex[8];
  158. // FVF stuff
  159. FVFDATA m_fvfData;
  160. // Used to store the old last pixel setting when drawing line strips.
  161. UINT m_uFlags;
  162. static DWORD DetectBeadSet( void) throw();
  163. static const UINT c_uiBegan;
  164. public:
  165. CRGBContext( TPerDDrawData& PDDD, PORTABLE_CONTEXTCREATEDATA& ccd):
  166. TSubContext( PDDD, ccd),
  167. TDrawPrimitives2( c_DP2Bindings.begin(), c_DP2Bindings.end(),
  168. c_RecDP2Bindings.begin(), c_RecDP2Bindings.end()),
  169. m_uFlags( 0)
  170. {
  171. HRESULT hr= m_PrimProc.Initialize();
  172. assert( SUCCEEDED( hr)); // TODO: Can fail?
  173. // TODO: Remove this unextendable stuff?
  174. memset(&m_RastCtx, 0, sizeof(m_RastCtx));
  175. m_RastCtx.dwSize = sizeof(D3DI_RASTCTX);
  176. m_RastCtx.pdwRenderState[ D3DRENDERSTATE_SCENECAPTURE]= FALSE;
  177. // Hit our notification scheme here.
  178. NewColorBuffer();
  179. NewDepthBuffer();
  180. m_PrimProc.SetCtx(&m_RastCtx);
  181. // Initialize bead table enum
  182. m_RastCtx.BeadSet = (D3DI_BEADSET)DetectBeadSet();
  183. m_RastCtx.uDevVer = 0;
  184. // All render and texture stage state is initialized by
  185. // DIRECT3DDEVICEI::stateInitialize
  186. // Enable MMX Fast Paths (Monolithics) if a registry key for it is not 0
  187. m_RastCtx.dwMMXFPDisableMask[0] = 0x0; // enable MMX FP's by default
  188. }
  189. ~CRGBContext() throw() { }
  190. void NewColorBuffer()
  191. {
  192. End();
  193. TRTarget& ColorBuffer= GetColorBuffer();
  194. if( ColorBuffer.GetMemLocation()!= TRTarget::EMemLocation::None)
  195. {
  196. IRGBSurface* pVMSurface= ColorBuffer.GetVidMemRepresentation();
  197. m_RastCtx.iSurfaceStride= pVMSurface->GetGBLlPitch();
  198. m_RastCtx.iSurfaceStep= pVMSurface->GetBytesPerPixel();
  199. m_RastCtx.iSurfaceBitCount= m_RastCtx.iSurfaceStep* 8;
  200. m_RastCtx.iSurfaceType= pVMSurface->GetSpanTexFormat();
  201. m_RastCtx.Clip.left= m_RastCtx.Clip.top= 0;
  202. m_RastCtx.Clip.bottom= pVMSurface->GetGBLwHeight();
  203. m_RastCtx.Clip.right= pVMSurface->GetGBLwWidth();
  204. m_RastCtx.pDDS= reinterpret_cast<LPDIRECTDRAWSURFACE>(pVMSurface);
  205. }
  206. else
  207. {
  208. m_RastCtx.iSurfaceStride= 0;
  209. m_RastCtx.iSurfaceStep= 0;
  210. m_RastCtx.iSurfaceBitCount= 0;
  211. m_RastCtx.iSurfaceType= D3DI_SPTFMT_NULL;
  212. m_RastCtx.Clip.left= m_RastCtx.Clip.top= 0;
  213. m_RastCtx.Clip.right= m_RastCtx.Clip.bottom= 0;
  214. m_RastCtx.pDDS= NULL;
  215. }
  216. TSubContext::NewColorBuffer();
  217. }
  218. void NewDepthBuffer()
  219. {
  220. End();
  221. TRTarget& DepthBuffer= GetDepthBuffer();
  222. if( DepthBuffer.GetMemLocation()!= TRTarget::EMemLocation::None)
  223. {
  224. IRGBSurface* pVMSurface= DepthBuffer.GetVidMemRepresentation();
  225. m_RastCtx.pZBits= NULL;
  226. m_RastCtx.iZStride= pVMSurface->GetGBLlPitch();
  227. m_RastCtx.iZStep= pVMSurface->GetBytesPerPixel();
  228. m_RastCtx.iZBitCount= m_RastCtx.iZStep* 8;
  229. m_RastCtx.pDDSZ= reinterpret_cast<LPDIRECTDRAWSURFACE>(pVMSurface);
  230. }
  231. else
  232. {
  233. m_RastCtx.pZBits= NULL;
  234. m_RastCtx.iZStride= 0;
  235. m_RastCtx.iZBitCount= 0;
  236. m_RastCtx.iZStep= 0;
  237. m_RastCtx.pDDSZ= NULL;
  238. }
  239. TSubContext::NewDepthBuffer();
  240. }
  241. HRESULT DP2ViewportInfo( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND* pCmd,
  242. const void* pP) throw()
  243. {
  244. const D3DHAL_DP2VIEWPORTINFO* pParam= reinterpret_cast<
  245. const D3DHAL_DP2VIEWPORTINFO*>(pP);
  246. // TODO: Roll into RGBContext (This particularly into DX8SDDIFW).
  247. m_RastCtx.Clip.left = pParam->dwX;
  248. m_RastCtx.Clip.top = pParam->dwY;
  249. m_RastCtx.Clip.bottom = pParam->dwY + pParam->dwHeight;
  250. m_RastCtx.Clip.right = pParam->dwX + pParam->dwWidth;
  251. return DD_OK;
  252. }
  253. operator D3DHAL_DP2VIEWPORTINFO() const throw()
  254. {
  255. D3DHAL_DP2VIEWPORTINFO Ret;
  256. Ret.dwX= m_RastCtx.Clip.left;
  257. Ret.dwY= m_RastCtx.Clip.top;
  258. Ret.dwWidth= m_RastCtx.Clip.right- Ret.dwX;
  259. Ret.dwHeight= m_RastCtx.Clip.bottom- Ret.dwY;
  260. return Ret;
  261. }
  262. void GetDP2ViewportInfo( D3DHAL_DP2VIEWPORTINFO& Param) const throw()
  263. { Param= (*this); }
  264. HRESULT RecDP2ViewportInfo( const D3DHAL_DP2COMMAND* pCmd, void* pP) throw()
  265. {
  266. D3DHAL_DP2VIEWPORTINFO* pParam= reinterpret_cast<
  267. D3DHAL_DP2VIEWPORTINFO*>(pP);
  268. pParam->dwX= m_RastCtx.Clip.left;
  269. pParam->dwY= m_RastCtx.Clip.top;
  270. pParam->dwWidth= m_RastCtx.Clip.right- m_RastCtx.Clip.left;
  271. pParam->dwHeight= m_RastCtx.Clip.bottom- m_RastCtx.Clip.top;
  272. return DD_OK;
  273. }
  274. HRESULT SetRenderState( UINT32 uState, UINT32 uStateVal)
  275. {
  276. m_RastCtx.pdwRenderState[uState] = uStateVal;
  277. switch(uState)
  278. {
  279. case D3DRS_CULLMODE:
  280. // Set face culling sign from state.
  281. switch(uStateVal)
  282. {
  283. case D3DCULL_CCW:
  284. m_RastCtx.uCullFaceSign= 1;
  285. break;
  286. case D3DCULL_CW:
  287. m_RastCtx.uCullFaceSign= 0;
  288. break;
  289. case D3DCULL_NONE:
  290. m_RastCtx.uCullFaceSign= 2;
  291. break;
  292. }
  293. break;
  294. case D3DRS_LASTPIXEL:
  295. // Set last-pixel flag from state.
  296. if (uStateVal)
  297. {
  298. m_PrimProc.SetFlags(PPF_DRAW_LAST_LINE_PIXEL);
  299. }
  300. else
  301. {
  302. m_PrimProc.ClrFlags(PPF_DRAW_LAST_LINE_PIXEL);
  303. }
  304. break;
  305. default:
  306. break;
  307. }
  308. return DD_OK;
  309. }
  310. HRESULT DP2RenderState( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND* pCmd,
  311. const void* pP)
  312. {
  313. const D3DHAL_DP2RENDERSTATE* pParam=
  314. reinterpret_cast<const D3DHAL_DP2RENDERSTATE*>(pP);
  315. WORD wStateCount( pCmd->wStateCount);
  316. HRESULT hr( DD_OK);
  317. End();
  318. D3DHAL_DP2RENDERSTATE SCap;
  319. SCap.RenderState= static_cast< D3DRENDERSTATETYPE>(
  320. D3DRENDERSTATE_SCENECAPTURE);
  321. GetDP2RenderState( SCap);
  322. const DWORD dwOldSC( SCap.dwState);
  323. if((DP2Data.dwFlags()& D3DHALDP2_EXECUTEBUFFER)!= 0)
  324. {
  325. // dp2d.lpdwRStates should be valid.
  326. if( wStateCount) do
  327. {
  328. assert( pParam->RenderState< D3DHAL_MAX_RSTATES);
  329. hr= SetRenderState( pParam->RenderState, pParam->dwState);
  330. if( SUCCEEDED(hr))
  331. DP2Data.lpdwRStates()[ pParam->RenderState]= pParam->dwState;
  332. ++pParam;
  333. } while( SUCCEEDED(hr)&& --wStateCount);
  334. }
  335. else
  336. {
  337. if( wStateCount) do
  338. {
  339. assert( pParam->RenderState< D3DHAL_MAX_RSTATES);
  340. hr= SetRenderState( pParam->RenderState, pParam->dwState);
  341. ++pParam;
  342. } while( SUCCEEDED(hr)&& --wStateCount);
  343. }
  344. GetDP2RenderState( SCap);
  345. if( FALSE== dwOldSC && TRUE== SCap.dwState)
  346. OnSceneCaptureStart();
  347. else if( TRUE== dwOldSC && FALSE== SCap.dwState)
  348. OnSceneCaptureEnd();
  349. return hr;
  350. }
  351. DWORD GetRenderStateDW( D3DRENDERSTATETYPE RS) const throw()
  352. { assert( RS< D3DHAL_MAX_RSTATES); return m_RastCtx.pdwRenderState[ RS]; }
  353. D3DVALUE GetRenderStateDV( D3DRENDERSTATETYPE RS) const throw()
  354. {
  355. assert( RS< D3DHAL_MAX_RSTATES);
  356. return *(reinterpret_cast< const D3DVALUE*>( &m_RastCtx.pfRenderState[ RS]));
  357. }
  358. void GetDP2RenderState( D3DHAL_DP2RENDERSTATE& GetParam) const throw()
  359. { GetParam.dwState= GetRenderStateDW( GetParam.RenderState); }
  360. void OnSceneCaptureStart( void) throw()
  361. {
  362. #if defined(USE_ICECAP4)
  363. static bool bStarted( true);
  364. if( bStarted)
  365. StopProfile( PROFILE_THREADLEVEL, PROFILE_CURRENTID);
  366. else
  367. StartProfile( PROFILE_THREADLEVEL, PROFILE_CURRENTID);
  368. bStarted= !bStarted;
  369. CommentMarkProfile( 1, "SceneCaptureStart");
  370. #endif
  371. }
  372. void OnSceneCaptureEnd( void) throw()
  373. {
  374. #if defined(USE_ICECAP4)
  375. CommentMarkProfile( 2, "SceneCaptureEnd");
  376. // StopProfile( PROFILE_THREADLEVEL, PROFILE_CURRENTID);
  377. #endif
  378. End();
  379. }
  380. void OnEndDrawPrimitives2( TDP2Data& )
  381. {
  382. End();
  383. }
  384. HRESULT SetTextureStageState( DWORD dwStage, DWORD dwState, DWORD uStateVal)
  385. {
  386. UINT cNewActTex = 0;
  387. m_RastCtx.pdwTextureStageState[dwStage][dwState] = uStateVal;
  388. switch (dwState)
  389. {
  390. case D3DTSS_TEXTUREMAP:
  391. {
  392. const TPerDDrawData::TSurfDBEntry* pTexDBEntry=
  393. GetPerDDrawData().GetSurfDBEntry( uStateVal);
  394. if( pTexDBEntry!= NULL)
  395. {
  396. assert((pTexDBEntry->GetLCLddsCaps().dwCaps& DDSCAPS_TEXTURE)!= 0);
  397. memset( &m_aSpanTex[ dwStage], 0, sizeof(m_aSpanTex[0]));
  398. m_aSpanTex[ dwStage].dwSize= sizeof(m_aSpanTex[0]);
  399. m_RastCtx.pTexture[ dwStage]= &m_aSpanTex[ dwStage];
  400. // Appears that a unique num is needed, but looks like
  401. // field isn't used anywhere. Using handle...
  402. m_aSpanTex[ dwStage].iGeneration= uStateVal;
  403. assert((pTexDBEntry->GetLCLdwFlags()& DDRAWISURF_HASCKEYSRCBLT)== 0);
  404. m_aSpanTex[ dwStage].uFlags&= ~D3DI_SPANTEX_HAS_TRANSPARENT;
  405. m_aSpanTex[ dwStage].Format= ConvPixelFormat( pTexDBEntry->GetGBLddpfSurface());
  406. if( m_aSpanTex[ dwStage].Format== D3DI_SPTFMT_PALETTE8 ||
  407. m_aSpanTex[ dwStage].Format== D3DI_SPTFMT_PALETTE4)
  408. {
  409. TPalDBEntry* pPalDBEntry= pTexDBEntry->GetPalette();
  410. assert( pPalDBEntry!= NULL);
  411. if((pPalDBEntry->GetFlags()& DDRAWIPAL_ALPHA)!= 0)
  412. m_aSpanTex[ dwStage].uFlags|= D3DI_SPANTEX_ALPHAPALETTE;
  413. m_aSpanTex[ dwStage].pPalette= reinterpret_cast<PUINT32>(
  414. pPalDBEntry->GetEntries());
  415. if( m_aSpanTex[ dwStage].Format== D3DI_SPTFMT_PALETTE8)
  416. m_aSpanTex[ dwStage].iPaletteSize = 256;
  417. else
  418. {
  419. // PALETTE4
  420. m_aSpanTex[ dwStage].iPaletteSize = 16;
  421. }
  422. }
  423. m_aSpanTex[ dwStage].TexAddrU= D3DTADDRESS_WRAP;
  424. m_aSpanTex[ dwStage].TexAddrV= D3DTADDRESS_WRAP;
  425. m_aSpanTex[ dwStage].BorderColor= RGBA_MAKE(0xff, 0x00, 0xff, 0xff);
  426. // assign first pSurf here (mipmap chain gets assigned below)
  427. m_aSpanTex[ dwStage].pSurf[0]= (LPDIRECTDRAWSURFACE)(pTexDBEntry);
  428. // Check for mipmap if any.
  429. const TPerDDrawData::TSurfDBEntry* pLcl= pTexDBEntry;
  430. // iPreSizeU and iPreSizeV store the size(u and v) of the previous level
  431. // mipmap. They are init'ed with the first texture size.
  432. INT16 iPreSizeU = m_aSpanTex[ dwStage].iSizeU, iPreSizeV = m_aSpanTex[ dwStage].iSizeV;
  433. for (;;)
  434. {
  435. TPerDDrawData::TSurfDBEntry::THandleVector::const_iterator
  436. itNextTexHandle;
  437. itNextTexHandle= find_if( pLcl->GetAttachedTo().begin(),
  438. pLcl->GetAttachedTo().end(),
  439. SHandleHasCaps( GetPerDDrawData(), DDSCAPS_TEXTURE));
  440. if( pLcl->GetAttachedTo().end()== itNextTexHandle)
  441. break;
  442. pLcl= GetPerDDrawData().GetSurfDBEntry( *itNextTexHandle);
  443. assert( pLcl!= NULL);
  444. m_aSpanTex[ dwStage].cLODTex++;
  445. m_aSpanTex[ dwStage].pSurf[m_aSpanTex[ dwStage].cLODTex]= (LPDIRECTDRAWSURFACE)pLcl;
  446. }
  447. SetSizesSpanTexture( &m_aSpanTex[ dwStage]);
  448. }
  449. else
  450. m_RastCtx.pTexture[ dwStage]= NULL;
  451. if( m_RastCtx.pTexture[dwStage]!= NULL)
  452. {
  453. m_RastCtx.pTexture[dwStage]->TexAddrU=
  454. (D3DTEXTUREADDRESS)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_ADDRESSU]);
  455. m_RastCtx.pTexture[dwStage]->TexAddrV=
  456. (D3DTEXTUREADDRESS)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_ADDRESSV]);
  457. m_RastCtx.pTexture[dwStage]->BorderColor=
  458. (D3DCOLOR)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_BORDERCOLOR]);
  459. m_RastCtx.pTexture[dwStage]->uMagFilter=
  460. (D3DTEXTUREMAGFILTER)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MAGFILTER]);
  461. m_RastCtx.pTexture[dwStage]->uMinFilter=
  462. (D3DTEXTUREMINFILTER)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MINFILTER]);
  463. m_RastCtx.pTexture[dwStage]->uMipFilter=
  464. (D3DTEXTUREMIPFILTER)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MIPFILTER]);
  465. m_RastCtx.pTexture[dwStage]->fLODBias=
  466. m_RastCtx.pfTextureStageState[dwStage][D3DTSS_MIPMAPLODBIAS];
  467. if( m_RastCtx.pTexture[dwStage]->iMaxMipLevel!=
  468. (INT32)m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MAXMIPLEVEL])
  469. {
  470. m_RastCtx.pTexture[dwStage]->iMaxMipLevel=
  471. (INT32)m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MAXMIPLEVEL];
  472. m_RastCtx.pTexture[dwStage]->uFlags|= D3DI_SPANTEX_MAXMIPLEVELS_DIRTY;
  473. }
  474. }
  475. // conservative but correct
  476. D3DHAL_VALIDATETEXTURESTAGESTATEDATA FakeVTSSD;
  477. FakeVTSSD.dwhContext= reinterpret_cast< ULONG_PTR>(this);
  478. FakeVTSSD.dwFlags= 0;
  479. FakeVTSSD.dwReserved= 0;
  480. FakeVTSSD.dwNumPasses= 0;
  481. FakeVTSSD.ddrval= DD_OK;
  482. if((FakeVTSSD.ddrval= ValidateTextureStageState( FakeVTSSD))== DD_OK)
  483. {
  484. // count number of contiguous-from-zero active texture blend stages
  485. for( INT iStage=0; iStage< D3DHAL_TSS_MAXSTAGES; iStage++)
  486. {
  487. // check for disabled stage (subsequent are thus inactive)
  488. // also conservatively checks for incorrectly enabled stage (might be legacy)
  489. if((m_RastCtx.pdwTextureStageState[iStage][D3DTSS_COLOROP]==
  490. D3DTOP_DISABLE) || (m_RastCtx.pTexture[iStage]== NULL))
  491. {
  492. break;
  493. }
  494. // stage is active
  495. cNewActTex++;
  496. }
  497. }
  498. if( m_RastCtx.cActTex!= cNewActTex)
  499. {
  500. m_RastCtx.StatesDirtyBits[D3DRENDERSTATE_TEXTUREHANDLE>>3]|=
  501. (1<<(D3DRENDERSTATE_TEXTUREHANDLE& 7));
  502. m_RastCtx.StatesDirtyBits[D3DHAL_MAX_RSTATES_AND_STAGES>>3]|=
  503. (1<<(D3DHAL_MAX_RSTATES_AND_STAGES& 7));
  504. m_RastCtx.cActTex= cNewActTex;
  505. }
  506. break;
  507. }
  508. case D3DTSS_ADDRESSU:
  509. case D3DTSS_ADDRESSV:
  510. case D3DTSS_MIPMAPLODBIAS:
  511. case D3DTSS_MAXMIPLEVEL:
  512. case D3DTSS_BORDERCOLOR:
  513. case D3DTSS_MAGFILTER:
  514. case D3DTSS_MINFILTER:
  515. case D3DTSS_MIPFILTER:
  516. if( m_RastCtx.pTexture[dwStage]!= NULL)
  517. {
  518. m_RastCtx.pTexture[dwStage]->TexAddrU=
  519. (D3DTEXTUREADDRESS)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_ADDRESSU]);
  520. m_RastCtx.pTexture[dwStage]->TexAddrV=
  521. (D3DTEXTUREADDRESS)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_ADDRESSV]);
  522. m_RastCtx.pTexture[dwStage]->BorderColor=
  523. (D3DCOLOR)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_BORDERCOLOR]);
  524. m_RastCtx.pTexture[dwStage]->uMagFilter=
  525. (D3DTEXTUREMAGFILTER)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MAGFILTER]);
  526. m_RastCtx.pTexture[dwStage]->uMinFilter=
  527. (D3DTEXTUREMINFILTER)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MINFILTER]);
  528. m_RastCtx.pTexture[dwStage]->uMipFilter=
  529. (D3DTEXTUREMIPFILTER)(m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MIPFILTER]);
  530. m_RastCtx.pTexture[dwStage]->fLODBias=
  531. m_RastCtx.pfTextureStageState[dwStage][D3DTSS_MIPMAPLODBIAS];
  532. if( m_RastCtx.pTexture[dwStage]->iMaxMipLevel!=
  533. (INT32)m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MAXMIPLEVEL])
  534. {
  535. m_RastCtx.pTexture[dwStage]->iMaxMipLevel=
  536. (INT32)m_RastCtx.pdwTextureStageState[dwStage][D3DTSS_MAXMIPLEVEL];
  537. m_RastCtx.pTexture[dwStage]->uFlags|= D3DI_SPANTEX_MAXMIPLEVELS_DIRTY;
  538. }
  539. }
  540. break;
  541. case D3DTSS_COLOROP:
  542. case D3DTSS_COLORARG1:
  543. case D3DTSS_COLORARG2:
  544. case D3DTSS_ALPHAOP:
  545. case D3DTSS_ALPHAARG1:
  546. case D3DTSS_ALPHAARG2:
  547. {
  548. // anything that effects the validity of the texture blending
  549. // could change the number of active texture stages
  550. // conservative but correct
  551. D3DHAL_VALIDATETEXTURESTAGESTATEDATA FakeVTSSD;
  552. FakeVTSSD.dwhContext= reinterpret_cast< ULONG_PTR>(this);
  553. FakeVTSSD.dwFlags= 0;
  554. FakeVTSSD.dwReserved= 0;
  555. FakeVTSSD.dwNumPasses= 0;
  556. FakeVTSSD.ddrval= DD_OK;
  557. if((FakeVTSSD.ddrval= ValidateTextureStageState( FakeVTSSD))== DD_OK)
  558. {
  559. // count number of contiguous-from-zero active texture blend stages
  560. for( INT iStage=0; iStage< D3DHAL_TSS_MAXSTAGES; iStage++)
  561. {
  562. // check for disabled stage (subsequent are thus inactive)
  563. // also conservatively checks for incorrectly enabled stage (might be legacy)
  564. if((m_RastCtx.pdwTextureStageState[iStage][D3DTSS_COLOROP]==
  565. D3DTOP_DISABLE) || (m_RastCtx.pTexture[iStage]== NULL))
  566. {
  567. break;
  568. }
  569. // stage is active
  570. cNewActTex++;
  571. }
  572. }
  573. m_RastCtx.cActTex= cNewActTex;
  574. break;
  575. }
  576. }
  577. return DD_OK;
  578. }
  579. HRESULT DP2TextureStageState( TDP2Data& DP2Data, const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  580. {
  581. const D3DHAL_DP2TEXTURESTAGESTATE* pParam=
  582. reinterpret_cast<const D3DHAL_DP2TEXTURESTAGESTATE*>(pP);
  583. WORD wStateCount( pCmd->wStateCount);
  584. HRESULT hr( DD_OK);
  585. End();
  586. if( wStateCount) do
  587. {
  588. assert( pParam->TSState< D3DTSS_MAX);
  589. hr= SetTextureStageState( pParam->wStage, pParam->TSState, pParam->dwValue);
  590. ++pParam;
  591. } while( SUCCEEDED(hr)&& --wStateCount);
  592. return hr;
  593. }
  594. DWORD GetTextureStageStateDW( WORD wStage, WORD wTSState) const throw()
  595. { return m_RastCtx.pdwTextureStageState[ wStage][ wTSState]; }
  596. D3DVALUE GetTextureStageStateDV( WORD wStage, WORD wTSState) const throw()
  597. {
  598. return *(reinterpret_cast< const D3DVALUE*>(
  599. &m_RastCtx.pdwTextureStageState[ wStage][ wTSState]));
  600. }
  601. void GetDP2TextureStageState( D3DHAL_DP2TEXTURESTAGESTATE& GetParam) const
  602. throw()
  603. { GetParam.dwValue= GetTextureStageStateDW( GetParam.wStage, GetParam.TSState); }
  604. HRESULT ValidateTextureStageState( D3DHAL_VALIDATETEXTURESTAGESTATEDATA&
  605. vtssd) const throw()
  606. {
  607. vtssd.dwNumPasses= 1;
  608. if ((m_RastCtx.pTexture[0] == m_RastCtx.pTexture[1]) &&
  609. (m_RastCtx.pTexture[0] != NULL) )
  610. {
  611. // except under very special circumstances, this will not work in RGB/MMX
  612. // since we keep a lot of stage state in the D3DI_SPANTEX structure
  613. return D3DERR_TOOMANYOPERATIONS;
  614. }
  615. for (INT i = 0; i < D3DHAL_TSS_MAXSTAGES; i++)
  616. {
  617. switch(m_RastCtx.pdwTextureStageState[i][D3DTSS_COLOROP])
  618. {
  619. default:
  620. return D3DERR_UNSUPPORTEDCOLOROPERATION;
  621. case D3DTOP_DISABLE:
  622. return DD_OK; // don't have to validate further if the stage is disabled
  623. case D3DTOP_SELECTARG1:
  624. case D3DTOP_SELECTARG2:
  625. case D3DTOP_MODULATE:
  626. case D3DTOP_MODULATE2X:
  627. case D3DTOP_MODULATE4X:
  628. case D3DTOP_ADD:
  629. case D3DTOP_ADDSIGNED:
  630. case D3DTOP_BLENDDIFFUSEALPHA:
  631. case D3DTOP_BLENDTEXTUREALPHA:
  632. case D3DTOP_BLENDFACTORALPHA:
  633. case D3DTOP_BLENDTEXTUREALPHAPM:
  634. case D3DTOP_ADDSIGNED2X:
  635. case D3DTOP_SUBTRACT:
  636. case D3DTOP_ADDSMOOTH:
  637. case D3DTOP_MODULATEALPHA_ADDCOLOR:
  638. case D3DTOP_MODULATECOLOR_ADDALPHA:
  639. break;
  640. }
  641. switch(m_RastCtx.pdwTextureStageState[i][D3DTSS_COLORARG1] &
  642. ~(D3DTA_ALPHAREPLICATE|D3DTA_COMPLEMENT))
  643. {
  644. default:
  645. return D3DERR_UNSUPPORTEDCOLORARG;
  646. case (D3DTA_TEXTURE):
  647. break;
  648. }
  649. switch(m_RastCtx.pdwTextureStageState[i][D3DTSS_COLORARG2] &
  650. ~(D3DTA_ALPHAREPLICATE|D3DTA_COMPLEMENT))
  651. {
  652. default:
  653. return D3DERR_UNSUPPORTEDCOLORARG;
  654. case (D3DTA_TFACTOR):
  655. case (D3DTA_CURRENT):
  656. case (D3DTA_DIFFUSE):
  657. case (D3DTA_SPECULAR):
  658. break;
  659. }
  660. switch(m_RastCtx.pdwTextureStageState[i][D3DTSS_ALPHAOP])
  661. {
  662. default:
  663. return D3DERR_UNSUPPORTEDALPHAOPERATION;
  664. case D3DTOP_DISABLE:
  665. break;
  666. case D3DTOP_SELECTARG1:
  667. case D3DTOP_SELECTARG2:
  668. case D3DTOP_MODULATE:
  669. case D3DTOP_MODULATE2X:
  670. case D3DTOP_MODULATE4X:
  671. case D3DTOP_ADD:
  672. case D3DTOP_ADDSIGNED:
  673. case D3DTOP_BLENDDIFFUSEALPHA:
  674. case D3DTOP_BLENDTEXTUREALPHA:
  675. case D3DTOP_BLENDFACTORALPHA:
  676. case D3DTOP_BLENDTEXTUREALPHAPM:
  677. case D3DTOP_ADDSIGNED2X:
  678. case D3DTOP_SUBTRACT:
  679. case D3DTOP_ADDSMOOTH:
  680. // only validate alpha args if alpha op is not disable
  681. switch(m_RastCtx.pdwTextureStageState[i][D3DTSS_ALPHAARG1] &
  682. ~(D3DTA_ALPHAREPLICATE|D3DTA_COMPLEMENT))
  683. {
  684. default:
  685. return D3DERR_UNSUPPORTEDALPHAARG;
  686. case (D3DTA_TEXTURE):
  687. break;
  688. }
  689. switch(m_RastCtx.pdwTextureStageState[i][D3DTSS_ALPHAARG2] &
  690. ~(D3DTA_ALPHAREPLICATE|D3DTA_COMPLEMENT))
  691. {
  692. default:
  693. return D3DERR_UNSUPPORTEDALPHAARG;
  694. case (D3DTA_TFACTOR):
  695. case (D3DTA_CURRENT):
  696. case (D3DTA_DIFFUSE):
  697. case (D3DTA_SPECULAR):
  698. break;
  699. }
  700. break;
  701. }
  702. }
  703. return DD_OK;
  704. }
  705. HRESULT DP2Clear( TDP2Data& DP2Data,
  706. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  707. {
  708. End();
  709. return TSubContext::DP2Clear( DP2Data, pCmd, pP);
  710. }
  711. HRESULT CheckFVF(DWORD dwFVF)
  712. {
  713. // check if FVF controls have changed
  714. if ( (m_fvfData.preFVF == dwFVF) &&
  715. (m_fvfData.TexIdx[0] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[0][D3DTSS_TEXCOORDINDEX])) &&
  716. (m_fvfData.TexIdx[1] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[1][D3DTSS_TEXCOORDINDEX])) &&
  717. (m_fvfData.TexIdx[2] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[2][D3DTSS_TEXCOORDINDEX])) &&
  718. (m_fvfData.TexIdx[3] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[3][D3DTSS_TEXCOORDINDEX])) &&
  719. (m_fvfData.TexIdx[4] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[4][D3DTSS_TEXCOORDINDEX])) &&
  720. (m_fvfData.TexIdx[5] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[5][D3DTSS_TEXCOORDINDEX])) &&
  721. (m_fvfData.TexIdx[6] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[6][D3DTSS_TEXCOORDINDEX])) &&
  722. (m_fvfData.TexIdx[7] == (INT)(0xffff&m_RastCtx.pdwTextureStageState[7][D3DTSS_TEXCOORDINDEX])) &&
  723. (m_fvfData.cActTex == m_RastCtx.cActTex) )
  724. {
  725. return D3D_OK;
  726. }
  727. memset(&m_fvfData, 0, sizeof(FVFDATA));
  728. m_fvfData.preFVF = dwFVF;
  729. INT32 i;
  730. for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i++)
  731. {
  732. m_fvfData.TexIdx[i] = 0xffff&m_RastCtx.pdwTextureStageState[i][D3DTSS_TEXCOORDINDEX];
  733. }
  734. m_fvfData.cActTex = m_RastCtx.cActTex;
  735. // XYZ
  736. if ( (dwFVF & (D3DFVF_RESERVED0 | D3DFVF_RESERVED2 |
  737. D3DFVF_NORMAL)) ||
  738. ((dwFVF & (D3DFVF_XYZ | D3DFVF_XYZRHW)) == 0) )
  739. {
  740. // can't set reserved bits, shouldn't have normals in
  741. // output to rasterizers, and must have coordinates
  742. return DDERR_INVALIDPARAMS;
  743. }
  744. m_fvfData.stride = sizeof(D3DVALUE) * 3;
  745. if (dwFVF & D3DFVF_XYZRHW)
  746. {
  747. m_fvfData.offsetRHW = m_fvfData.stride;
  748. m_fvfData.stride += sizeof(D3DVALUE);
  749. }
  750. if (dwFVF & D3DFVF_PSIZE)
  751. {
  752. m_fvfData.offsetPSize = m_fvfData.stride;
  753. m_fvfData.stride += sizeof(D3DVALUE);
  754. }
  755. if (dwFVF & D3DFVF_DIFFUSE)
  756. {
  757. m_fvfData.offsetDiff = m_fvfData.stride;
  758. m_fvfData.stride += sizeof(D3DCOLOR);
  759. }
  760. if (dwFVF & D3DFVF_SPECULAR)
  761. {
  762. m_fvfData.offsetSpec = m_fvfData.stride;
  763. m_fvfData.stride += sizeof(D3DCOLOR);
  764. }
  765. INT iTexCount = (dwFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
  766. if (iTexCount > 0)
  767. {
  768. // set offset for Textures
  769. for ( i = 0; i < D3DHAL_TSS_MAXSTAGES; i ++)
  770. {
  771. m_fvfData.offsetTex[i] = (SHORT)(m_fvfData.stride +
  772. 2*sizeof(D3DVALUE)*m_fvfData.TexIdx[i]);
  773. }
  774. // update stride
  775. m_fvfData.stride += (USHORT)(iTexCount * (sizeof(D3DVALUE) * 2));
  776. }
  777. if( D3DFVF_TLVERTEX== dwFVF)
  778. m_fvfData.vtxType = RAST_TLVERTEX;
  779. else
  780. m_fvfData.vtxType = RAST_GENVERTEX;
  781. return D3D_OK;
  782. }
  783. void PackGenVertex(PUINT8 pFvfVtx, RAST_GENERIC_VERTEX *pGenVtx)
  784. {
  785. pGenVtx->sx = *((D3DVALUE *)pFvfVtx);
  786. pGenVtx->sy = *((D3DVALUE *)pFvfVtx + 1);
  787. pGenVtx->sz = *((D3DVALUE *)pFvfVtx + 2);
  788. if (m_fvfData.offsetRHW)
  789. {
  790. pGenVtx->rhw = *((D3DVALUE *)(pFvfVtx + m_fvfData.offsetRHW));
  791. }
  792. else
  793. {
  794. pGenVtx->rhw = 1.0f;
  795. }
  796. if (m_fvfData.offsetDiff)
  797. {
  798. pGenVtx->color = *((D3DCOLOR *)(pFvfVtx + m_fvfData.offsetDiff));
  799. }
  800. else
  801. {
  802. pGenVtx->color = 0xFFFFFFFF; //__DEFAULT_DIFFUSE;
  803. }
  804. if (m_fvfData.offsetSpec)
  805. {
  806. pGenVtx->specular = *((D3DCOLOR *)(pFvfVtx + m_fvfData.offsetSpec));
  807. }
  808. else
  809. {
  810. pGenVtx->specular = 0; //__DEFAULT_SPECULAR;
  811. }
  812. for (INT32 i = 0; i < (INT32)m_fvfData.cActTex; i++)
  813. {
  814. if (m_fvfData.offsetTex[i])
  815. {
  816. pGenVtx->texCoord[i].tu = *((D3DVALUE *)(pFvfVtx + m_fvfData.offsetTex[i]));
  817. pGenVtx->texCoord[i].tv = *((D3DVALUE *)(pFvfVtx + m_fvfData.offsetTex[i]) + 1);
  818. }
  819. else
  820. {
  821. pGenVtx->texCoord[i].tu = 0.0f;
  822. pGenVtx->texCoord[i].tv = 0.0f;
  823. }
  824. }
  825. }
  826. HRESULT DP2DrawPrimitive( TDP2Data& DP2Data,
  827. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  828. {
  829. const D3DHAL_DP2DRAWPRIMITIVE* pParam= reinterpret_cast<
  830. const D3DHAL_DP2DRAWPRIMITIVE*>(pP);
  831. HRESULT hr( DD_OK);
  832. const D3DHAL_DP2VERTEXSHADER VertexShader(*this);
  833. // We need this data.
  834. UINT8* pStartVData= NULL;
  835. DWORD dwVStride( 0);
  836. // Since RGB is a non TnL device, the vertex shader handle should
  837. // always be a fixed function FVF.
  838. const DWORD dwFVF( VertexShader.dwHandle);
  839. // Since RGB only supports one stream, our data source should be
  840. // from stream 0.
  841. TVStream& VStream0( m_VStreamDB[ 0]);
  842. VStream0.SetFVF( dwFVF);
  843. // Find vertex information.
  844. if( VStream0.GetMemLocation()== TVStream::EMemLocation::User)
  845. {
  846. pStartVData= reinterpret_cast< UINT8*>( VStream0.GetUserMemPtr());
  847. dwVStride= VStream0.GetStride();
  848. }
  849. else if( VStream0.GetMemLocation()== TVStream::EMemLocation::System||
  850. VStream0.GetMemLocation()== TVStream::EMemLocation::Video)
  851. {
  852. // RGB can pretend system mem and video mem surfaces are the same.
  853. pStartVData= reinterpret_cast< UINT8*>(
  854. VStream0.GetSurfDBRepresentation()->GetGBLfpVidMem());
  855. dwVStride= VStream0.GetStride();
  856. }
  857. if( pStartVData!= NULL)
  858. {
  859. Begin();
  860. WORD wPrimitiveCount( pCmd->wPrimitiveCount);
  861. hr= CheckFVF( dwFVF);
  862. assert( SUCCEEDED( hr));
  863. if( FAILED( hr)) wPrimitiveCount= 0;
  864. if( wPrimitiveCount) do
  865. {
  866. UINT8* pVData= pStartVData+ pParam->VStart* dwVStride;
  867. m_PrimProc.BeginPrimSet( pParam->primType, m_fvfData.vtxType);
  868. if( RAST_GENVERTEX== m_fvfData.vtxType)
  869. DoDrawOneGenPrimitive( dwVStride, pVData,
  870. pParam->primType, pParam->PrimitiveCount);
  871. else
  872. DoDrawOnePrimitive( dwVStride, pVData,
  873. pParam->primType, pParam->PrimitiveCount);
  874. } while( SUCCEEDED(hr) && --wPrimitiveCount);
  875. }
  876. return hr;
  877. }
  878. HRESULT DP2DrawPrimitive2( TDP2Data& DP2Data,
  879. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  880. {
  881. const D3DHAL_DP2DRAWPRIMITIVE2* pParam= reinterpret_cast<
  882. const D3DHAL_DP2DRAWPRIMITIVE2*>(pP);
  883. HRESULT hr( DD_OK);
  884. const D3DHAL_DP2VERTEXSHADER VertexShader(*this);
  885. // We need this data.
  886. UINT8* pStartVData= NULL;
  887. DWORD dwVStride( 0);
  888. // Since RGB is a non TnL device, the vertex shader handle should
  889. // always be a fixed function FVF.
  890. const DWORD dwFVF( VertexShader.dwHandle);
  891. // Since RGB only supports one stream, our data source should be
  892. // from stream 0.
  893. TVStream& VStream0( m_VStreamDB[ 0]);
  894. VStream0.SetFVF( dwFVF);
  895. // Find vertex information.
  896. if( VStream0.GetMemLocation()== TVStream::EMemLocation::User)
  897. {
  898. pStartVData= reinterpret_cast< UINT8*>( VStream0.GetUserMemPtr());
  899. dwVStride= VStream0.GetStride();
  900. }
  901. else if( VStream0.GetMemLocation()== TVStream::EMemLocation::System||
  902. VStream0.GetMemLocation()== TVStream::EMemLocation::Video)
  903. {
  904. // RGB can pretend system mem and video mem surfaces are the same.
  905. pStartVData= reinterpret_cast< UINT8*>(
  906. VStream0.GetSurfDBRepresentation()->GetGBLfpVidMem());
  907. dwVStride= VStream0.GetStride();
  908. }
  909. if( pStartVData!= NULL)
  910. {
  911. Begin();
  912. WORD wPrimitiveCount( pCmd->wPrimitiveCount);
  913. hr= CheckFVF( dwFVF);
  914. assert( SUCCEEDED( hr));
  915. if( FAILED( hr)) wPrimitiveCount= 0;
  916. if( wPrimitiveCount) do
  917. {
  918. UINT8* pVData= pStartVData+ pParam->FirstVertexOffset;
  919. m_PrimProc.BeginPrimSet( pParam->primType, m_fvfData.vtxType);
  920. if( RAST_GENVERTEX== m_fvfData.vtxType)
  921. DoDrawOneGenPrimitive( dwVStride, pVData,
  922. pParam->primType, pParam->PrimitiveCount);
  923. else
  924. DoDrawOnePrimitive( dwVStride, pVData,
  925. pParam->primType, pParam->PrimitiveCount);
  926. } while( SUCCEEDED(hr) && --wPrimitiveCount);
  927. }
  928. return hr;
  929. }
  930. HRESULT DP2DrawIndexedPrimitive( TDP2Data& DP2Data,
  931. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  932. {
  933. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE* pParam= reinterpret_cast<
  934. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE*>(pP);
  935. HRESULT hr( DD_OK);
  936. const D3DHAL_DP2VERTEXSHADER VertexShader(*this);
  937. // We need this data for rasterization.
  938. UINT8* pStartVData= NULL;
  939. UINT8* pStartIData= NULL;
  940. DWORD dwVStride( 0);
  941. DWORD dwIStride( 0);
  942. // Since RGB is a non TnL device, the vertex shader handle should
  943. // always be a fixed function FVF.
  944. const DWORD dwFVF( VertexShader.dwHandle);
  945. // Since RGB only supports one stream, our data source should be
  946. // from stream 0.
  947. TVStream& VStream0( m_VStreamDB[ 0]);
  948. VStream0.SetFVF( dwFVF);
  949. // Find vertex information.
  950. if( VStream0.GetMemLocation()== TVStream::EMemLocation::User)
  951. {
  952. pStartVData= reinterpret_cast< UINT8*>( VStream0.GetUserMemPtr());
  953. dwVStride= VStream0.GetStride();
  954. }
  955. else if( VStream0.GetMemLocation()== TVStream::EMemLocation::System||
  956. VStream0.GetMemLocation()== TVStream::EMemLocation::Video)
  957. {
  958. // RGB can pretend system mem and video mem surfaces are the same.
  959. pStartVData= reinterpret_cast< UINT8*>(
  960. VStream0.GetSurfDBRepresentation()->GetGBLfpVidMem());
  961. dwVStride= VStream0.GetStride();
  962. }
  963. // Find Indices information.
  964. const TIStream& IStream= GetIStream( 0);
  965. if( IStream.GetMemLocation()== TIStream::EMemLocation::System||
  966. IStream.GetMemLocation()== TIStream::EMemLocation::Video)
  967. {
  968. // RGB can pretend system mem and video mem surfaces are the same.
  969. pStartIData= reinterpret_cast< UINT8*>(
  970. IStream.GetSurfDBRepresentation()->GetGBLfpVidMem());
  971. dwIStride= IStream.GetStride();
  972. }
  973. if( pStartVData!= NULL&& pStartIData!= NULL&& sizeof(WORD)== dwIStride)
  974. {
  975. Begin();
  976. WORD wPrimitiveCount( pCmd->wPrimitiveCount);
  977. hr= CheckFVF( dwFVF);
  978. assert( SUCCEEDED( hr));
  979. if( FAILED( hr)) wPrimitiveCount= 0;
  980. if( wPrimitiveCount) do
  981. {
  982. UINT8* pVData= pStartVData+ pParam->BaseVertexIndex* dwVStride;
  983. UINT8* pIData= pStartIData+ pParam->StartIndex* dwIStride;
  984. m_PrimProc.BeginPrimSet( pParam->primType, m_fvfData.vtxType);
  985. if( RAST_GENVERTEX== m_fvfData.vtxType)
  986. DoDrawOneGenIndexedPrimitive( dwVStride, pVData,
  987. reinterpret_cast<WORD*>(pIData), pParam->primType,
  988. pParam->PrimitiveCount);
  989. else
  990. DoDrawOneIndexedPrimitive( dwVStride, pVData,
  991. reinterpret_cast<WORD*>(pIData), pParam->primType,
  992. pParam->PrimitiveCount);
  993. } while( SUCCEEDED(hr) && --wPrimitiveCount);
  994. }
  995. return hr;
  996. }
  997. HRESULT DP2DrawIndexedPrimitive2( TDP2Data& DP2Data,
  998. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  999. {
  1000. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE2* pParam= reinterpret_cast<
  1001. const D3DHAL_DP2DRAWINDEXEDPRIMITIVE2*>(pP);
  1002. HRESULT hr( DD_OK);
  1003. const D3DHAL_DP2VERTEXSHADER VertexShader(*this);
  1004. // We need this data for rasterization.
  1005. UINT8* pStartVData= NULL;
  1006. UINT8* pStartIData= NULL;
  1007. DWORD dwVStride( 0);
  1008. DWORD dwIStride( 0);
  1009. // Since RGB is a non TnL device, the vertex shader handle should
  1010. // always be a fixed function FVF.
  1011. const DWORD dwFVF( VertexShader.dwHandle);
  1012. // Since RGB only supports one stream, our data source should be
  1013. // from stream 0.
  1014. TVStream& VStream0( m_VStreamDB[ 0]);
  1015. VStream0.SetFVF( dwFVF);
  1016. // Find vertex information.
  1017. if( VStream0.GetMemLocation()== TVStream::EMemLocation::User)
  1018. {
  1019. pStartVData= reinterpret_cast< UINT8*>( VStream0.GetUserMemPtr());
  1020. dwVStride= VStream0.GetStride();
  1021. }
  1022. else if( VStream0.GetMemLocation()== TVStream::EMemLocation::System||
  1023. VStream0.GetMemLocation()== TVStream::EMemLocation::Video)
  1024. {
  1025. // RGB can pretend system mem and video mem surfaces are the same.
  1026. pStartVData= reinterpret_cast< UINT8*>(
  1027. VStream0.GetSurfDBRepresentation()->GetGBLfpVidMem());
  1028. dwVStride= VStream0.GetStride();
  1029. }
  1030. // Find Indices information.
  1031. const TIStream& IStream= GetIStream( 0);
  1032. if( IStream.GetMemLocation()== TIStream::EMemLocation::System||
  1033. IStream.GetMemLocation()== TIStream::EMemLocation::Video)
  1034. {
  1035. // RGB can pretend system mem and video mem surfaces are the same.
  1036. pStartIData= reinterpret_cast< UINT8*>(
  1037. IStream.GetSurfDBRepresentation()->GetGBLfpVidMem());
  1038. dwIStride= IStream.GetStride();
  1039. }
  1040. if( pStartVData!= NULL&& pStartIData!= NULL&& sizeof(WORD)== dwIStride)
  1041. {
  1042. Begin();
  1043. WORD wPrimitiveCount( pCmd->wPrimitiveCount);
  1044. hr= CheckFVF( dwFVF);
  1045. assert( SUCCEEDED( hr));
  1046. if( FAILED( hr)) wPrimitiveCount= 0;
  1047. if( wPrimitiveCount) do
  1048. {
  1049. UINT8* pVData= pStartVData+ pParam->BaseVertexOffset;
  1050. UINT8* pIData= pStartIData+ pParam->StartIndexOffset;
  1051. m_PrimProc.BeginPrimSet( pParam->primType, m_fvfData.vtxType);
  1052. if( RAST_GENVERTEX== m_fvfData.vtxType)
  1053. DoDrawOneGenIndexedPrimitive( dwVStride, pVData,
  1054. reinterpret_cast<WORD*>(pIData), pParam->primType,
  1055. pParam->PrimitiveCount);
  1056. else
  1057. DoDrawOneIndexedPrimitive( dwVStride, pVData,
  1058. reinterpret_cast<WORD*>(pIData), pParam->primType,
  1059. pParam->PrimitiveCount);
  1060. } while( SUCCEEDED(hr) && --wPrimitiveCount);
  1061. }
  1062. return hr;
  1063. }
  1064. HRESULT DP2ClippedTriangleFan( TDP2Data& DP2Data,
  1065. const D3DHAL_DP2COMMAND* pCmd, const void* pP)
  1066. {
  1067. const D3DHAL_CLIPPEDTRIANGLEFAN* pParam= reinterpret_cast<
  1068. const D3DHAL_CLIPPEDTRIANGLEFAN*>(pP);
  1069. HRESULT hr( DD_OK);
  1070. const D3DHAL_DP2VERTEXSHADER VertexShader(*this);
  1071. // We need this data.
  1072. UINT8* pStartVData= NULL;
  1073. DWORD dwVStride( 0);
  1074. // Since RGB is a non TnL device, the vertex shader handle should
  1075. // always be a fixed function FVF.
  1076. const DWORD dwFVF( VertexShader.dwHandle);
  1077. // Since RGB only supports one stream, our data source should be
  1078. // from stream 0.
  1079. TVStream& VStream0( m_VStreamDB[ 0]);
  1080. VStream0.SetFVF( dwFVF);
  1081. // Find vertex information.
  1082. if( VStream0.GetMemLocation()== TVStream::EMemLocation::User)
  1083. {
  1084. pStartVData= reinterpret_cast< UINT8*>( VStream0.GetUserMemPtr());
  1085. dwVStride= VStream0.GetStride();
  1086. }
  1087. else if( VStream0.GetMemLocation()== TVStream::EMemLocation::System||
  1088. VStream0.GetMemLocation()== TVStream::EMemLocation::Video)
  1089. {
  1090. // RGB can pretend system mem and video mem surfaces are the same.
  1091. pStartVData= reinterpret_cast< UINT8*>(
  1092. VStream0.GetSurfDBRepresentation()->GetGBLfpVidMem());
  1093. dwVStride= VStream0.GetStride();
  1094. }
  1095. if( pStartVData!= NULL)
  1096. {
  1097. Begin();
  1098. WORD wPrimitiveCount( pCmd->wPrimitiveCount);
  1099. hr= CheckFVF( dwFVF);
  1100. assert( SUCCEEDED( hr));
  1101. if( FAILED( hr)) wPrimitiveCount= 0;
  1102. if( wPrimitiveCount) do
  1103. {
  1104. UINT8* pVData= pStartVData+ pParam->FirstVertexOffset;
  1105. m_PrimProc.BeginPrimSet( D3DPT_TRIANGLEFAN, m_fvfData.vtxType);
  1106. if( RAST_GENVERTEX== m_fvfData.vtxType)
  1107. DoDrawOneGenEdgeFlagTriangleFan( dwVStride, pVData,
  1108. pParam->PrimitiveCount, pParam->dwEdgeFlags);
  1109. else
  1110. DoDrawOneEdgeFlagTriangleFan( dwVStride, pVData,
  1111. pParam->PrimitiveCount, pParam->dwEdgeFlags);
  1112. } while( SUCCEEDED(hr) && --wPrimitiveCount);
  1113. }
  1114. return hr;
  1115. }
  1116. void Begin()
  1117. {
  1118. HRESULT hr( DD_OK);
  1119. if((m_uFlags& c_uiBegan)!= 0)
  1120. return;
  1121. // TODO: call this less often?
  1122. UpdateColorKeyAndPalette();
  1123. // Check for state changes
  1124. BOOL bMaxMipLevelsDirty = FALSE;
  1125. for (INT j = 0; j < (INT)m_RastCtx.cActTex; j++)
  1126. {
  1127. PD3DI_SPANTEX pSpanTex = m_RastCtx.pTexture[j];
  1128. if (pSpanTex)
  1129. {
  1130. bMaxMipLevelsDirty = bMaxMipLevelsDirty || (pSpanTex->uFlags & D3DI_SPANTEX_MAXMIPLEVELS_DIRTY);
  1131. }
  1132. }
  1133. RastLockSpanTexture();
  1134. // Notify primitive Processor of state change.
  1135. m_PrimProc.StateChanged();
  1136. // Must call SpanInit AFTER texture is locked, since this
  1137. // sets various flags and fields that are needed for bead choosing
  1138. // Call SpanInit to setup the beads
  1139. hr= SpanInit(&m_RastCtx);
  1140. // Lock rendering target (must be VM Surfaces).
  1141. m_RastCtx.pSurfaceBits= reinterpret_cast<UINT8*>(
  1142. reinterpret_cast< TSurface*>(m_RastCtx.pDDS)->Lock( 0, NULL));
  1143. if( m_RastCtx.pDDSZ!= NULL)
  1144. {
  1145. m_RastCtx.pZBits= reinterpret_cast<UINT8*>(
  1146. reinterpret_cast< TSurface*>(m_RastCtx.pDDSZ)->Lock( 0, NULL));
  1147. }
  1148. else
  1149. {
  1150. m_RastCtx.pZBits = NULL;
  1151. }
  1152. // Prepare the primitive processor
  1153. m_PrimProc.Begin();
  1154. m_uFlags|= c_uiBegan;
  1155. }
  1156. void End( void)
  1157. {
  1158. if((m_uFlags& c_uiBegan)!= 0)
  1159. {
  1160. HRESULT hr = m_PrimProc.End();
  1161. assert( SUCCEEDED( hr));
  1162. // Unlock texture if this is not called in the middle of drawPrims to
  1163. // flush for possible state changes. In the 2nd case, let
  1164. // SetRenderState to handle it.
  1165. RastUnlockSpanTexture();
  1166. // Unlock surfaces
  1167. reinterpret_cast<TSurface*>(m_RastCtx.pDDS)->Unlock();
  1168. if( m_RastCtx.pDDSZ!= NULL)
  1169. reinterpret_cast<TSurface*>(m_RastCtx.pDDSZ)->Unlock();
  1170. m_uFlags&= ~c_uiBegan;
  1171. }
  1172. }
  1173. bool IsTextureOff(void)
  1174. {
  1175. return
  1176. (m_RastCtx.cActTex == 0 ||
  1177. (m_RastCtx.cActTex == 1 && m_RastCtx.pTexture[0] == NULL) ||
  1178. (m_RastCtx.cActTex == 2 &&
  1179. (m_RastCtx.pTexture[0] == NULL ||
  1180. m_RastCtx.pTexture[1] == NULL)));
  1181. }
  1182. void RastUnlockSpanTexture(void)
  1183. {
  1184. INT i, j;
  1185. PD3DI_SPANTEX pSpanTex;;
  1186. if (IsTextureOff())
  1187. {
  1188. return;
  1189. }
  1190. for (j = 0;
  1191. j < (INT)m_RastCtx.cActTex;
  1192. j++)
  1193. {
  1194. pSpanTex = m_RastCtx.pTexture[j];
  1195. INT iFirstSurf = min(pSpanTex->iMaxMipLevel, pSpanTex->cLODTex);
  1196. // RastUnlock is used for cleanup in RastLock so it needs to
  1197. // be able to handle partially locked mipmap chains.
  1198. if((pSpanTex->uFlags& D3DI_SPANTEX_SURFACES_LOCKED)!= 0)
  1199. {
  1200. for (i = iFirstSurf; i <= pSpanTex->cLODTex; i++)
  1201. {
  1202. const TPerDDrawData::TSurfDBEntry* pSurfDBEntry=
  1203. reinterpret_cast<const TPerDDrawData::TSurfDBEntry*>(
  1204. pSpanTex->pSurf[i]);
  1205. if((pSurfDBEntry->GetLCLddsCaps().dwCaps& DDSCAPS_VIDEOMEMORY)!= 0)
  1206. {
  1207. TSurface* pSurf= GetPerDDrawData().GetDriver().GetSurface( *pSurfDBEntry);
  1208. pSurf->Unlock();
  1209. pSpanTex->pBits[i-iFirstSurf]= NULL;
  1210. }
  1211. }
  1212. pSpanTex->uFlags&= ~D3DI_SPANTEX_SURFACES_LOCKED;
  1213. }
  1214. }
  1215. }
  1216. UINT32 static IntLog2(UINT32 x)
  1217. {
  1218. UINT32 y = 0;
  1219. x >>= 1;
  1220. while(x != 0)
  1221. {
  1222. x >>= 1;
  1223. y++;
  1224. }
  1225. return y;
  1226. }
  1227. static HRESULT SetSizesSpanTexture(PD3DI_SPANTEX pSpanTex)
  1228. {
  1229. const TPerDDrawData::TSurfDBEntry* pLcl;
  1230. INT iFirstSurf = min(pSpanTex->iMaxMipLevel, pSpanTex->cLODTex);
  1231. LPDIRECTDRAWSURFACE pDDS = pSpanTex->pSurf[iFirstSurf];
  1232. INT i;
  1233. // Init
  1234. pLcl = (const TPerDDrawData::TSurfDBEntry*)pDDS;
  1235. pSpanTex->iSizeU = (INT16)pLcl->GetGBLwWidth();
  1236. pSpanTex->iSizeV = (INT16)pLcl->GetGBLwHeight();
  1237. pSpanTex->uMaskU = (INT16)(pSpanTex->iSizeU - 1);
  1238. pSpanTex->uMaskV = (INT16)(pSpanTex->iSizeV - 1);
  1239. pSpanTex->iShiftU = (INT16)IntLog2(pSpanTex->iSizeU);
  1240. if (0 != pLcl->GetGBLddpfSurface().dwRGBBitCount)
  1241. {
  1242. pSpanTex->iShiftPitch[0] =
  1243. (INT16)IntLog2((UINT32)(pLcl->GetGBLlPitch()* 8)/
  1244. pLcl->GetGBLddpfSurface().dwRGBBitCount);
  1245. }
  1246. else
  1247. {
  1248. pSpanTex->iShiftPitch[0] =
  1249. (INT16)IntLog2(((UINT32)pLcl->GetGBLwWidth()* 8));
  1250. }
  1251. pSpanTex->iShiftV = (INT16)IntLog2(pSpanTex->iSizeV);
  1252. pSpanTex->uMaskV = pSpanTex->uMaskV;
  1253. // Check if the texture size is power of 2
  1254. /* if (!ValidTextureSize(pSpanTex->iSizeU, pSpanTex->iShiftU,
  1255. pSpanTex->iSizeV, pSpanTex->iShiftV))
  1256. {
  1257. return DDERR_INVALIDPARAMS;
  1258. }*/
  1259. // Check for mipmap if any.
  1260. // iPreSizeU and iPreSizeV store the size(u and v) of the previous level
  1261. // mipmap. They are init'ed with the first texture size.
  1262. INT16 iPreSizeU = pSpanTex->iSizeU, iPreSizeV = pSpanTex->iSizeV;
  1263. for ( i = iFirstSurf + 1; i <= pSpanTex->cLODTex; i++)
  1264. {
  1265. pDDS = pSpanTex->pSurf[i];
  1266. // Check for invalid mipmap texture size
  1267. pLcl = (const TPerDDrawData::TSurfDBEntry*)pDDS;
  1268. /* if (!ValidMipmapSize(iPreSizeU, (INT16)DDSurf_Width(pLcl)) ||
  1269. !ValidMipmapSize(iPreSizeV, (INT16)DDSurf_Height(pLcl)))
  1270. {
  1271. return DDERR_INVALIDPARAMS;
  1272. }*/
  1273. if (0 != pLcl->GetGBLddpfSurface().dwRGBBitCount)
  1274. {
  1275. pSpanTex->iShiftPitch[i - iFirstSurf] =
  1276. (INT16)IntLog2(((UINT32)pLcl->GetGBLlPitch()* 8)/
  1277. pLcl->GetGBLddpfSurface().dwRGBBitCount);
  1278. }
  1279. else
  1280. {
  1281. pSpanTex->iShiftPitch[i - iFirstSurf] =
  1282. (INT16)IntLog2(((UINT32)pLcl->GetGBLwWidth()*8));
  1283. }
  1284. iPreSizeU = (INT16)pLcl->GetGBLwWidth();
  1285. iPreSizeV = (INT16)pLcl->GetGBLwHeight();
  1286. }
  1287. pSpanTex->cLOD = pSpanTex->cLODTex - iFirstSurf;
  1288. pSpanTex->iMaxScaledLOD = ((pSpanTex->cLOD + 1) << LOD_SHIFT) - 1;
  1289. pSpanTex->uFlags &= ~D3DI_SPANTEX_MAXMIPLEVELS_DIRTY;
  1290. return DD_OK;
  1291. }
  1292. void RastLockSpanTexture(void)
  1293. {
  1294. INT i, j;
  1295. PD3DI_SPANTEX pSpanTex;
  1296. HRESULT hr;
  1297. if (IsTextureOff())
  1298. return;
  1299. for( j= 0; j< (INT)m_RastCtx.cActTex; j++)
  1300. {
  1301. pSpanTex= m_RastCtx.pTexture[j];
  1302. if((pSpanTex->uFlags& D3DI_SPANTEX_MAXMIPLEVELS_DIRTY)!= 0)
  1303. {
  1304. hr= SetSizesSpanTexture(pSpanTex);
  1305. if( hr!= D3D_OK)
  1306. {
  1307. RastUnlockSpanTexture();
  1308. return;
  1309. }
  1310. }
  1311. INT iFirstSurf = min(pSpanTex->iMaxMipLevel, pSpanTex->cLODTex);
  1312. for (i = iFirstSurf; i <= pSpanTex->cLODTex; i++)
  1313. {
  1314. const TPerDDrawData::TSurfDBEntry* pSurfDBEntry=
  1315. reinterpret_cast<const TPerDDrawData::TSurfDBEntry*>(
  1316. pSpanTex->pSurf[i]);
  1317. if((pSurfDBEntry->GetLCLddsCaps().dwCaps& DDSCAPS_VIDEOMEMORY)!= 0)
  1318. {
  1319. TSurface* pSurf= GetPerDDrawData().GetDriver().GetSurface( *pSurfDBEntry);
  1320. pSpanTex->pBits[i-iFirstSurf]= reinterpret_cast<UINT8*>(
  1321. pSurf->Lock( 0, NULL));
  1322. }
  1323. }
  1324. pSpanTex->uFlags|= D3DI_SPANTEX_SURFACES_LOCKED;
  1325. }
  1326. }
  1327. void UpdateColorKeyAndPalette()
  1328. {
  1329. // TODO: Palette
  1330. INT j;
  1331. PD3DI_SPANTEX pSpanTex;
  1332. // Set the transparent bit and the transparent color with pSurf[0]
  1333. const TPerDDrawData::TSurfDBEntry* pLcl;
  1334. for (j = 0; j < (INT)m_RastCtx.cActTex; j++)
  1335. {
  1336. pSpanTex = m_RastCtx.pTexture[j];
  1337. if ((pSpanTex != NULL) && (pSpanTex->pSurf[0] != NULL))
  1338. {
  1339. pLcl= (const TPerDDrawData::TSurfDBEntry*)(pSpanTex->pSurf[0]);
  1340. // Palette might be changed
  1341. if (pSpanTex->Format == D3DI_SPTFMT_PALETTE8 ||
  1342. pSpanTex->Format == D3DI_SPTFMT_PALETTE4)
  1343. {
  1344. TPalDBEntry* pPalDBEntry= pLcl->GetPalette();
  1345. assert( pPalDBEntry!= NULL);
  1346. if((pPalDBEntry->GetFlags()& DDRAWIPAL_ALPHA)!= 0)
  1347. pSpanTex->uFlags|= D3DI_SPANTEX_ALPHAPALETTE;
  1348. pSpanTex->pPalette= reinterpret_cast< PUINT32>(
  1349. pPalDBEntry->GetEntries());
  1350. }
  1351. // texture does not have a ColorKey value
  1352. if (pSpanTex->uFlags & D3DI_SPANTEX_HAS_TRANSPARENT)
  1353. {
  1354. pSpanTex->uFlags &= ~D3DI_SPANTEX_HAS_TRANSPARENT;
  1355. // TODO:
  1356. // make sure this state change is recognized, and a new
  1357. // texture read function is used
  1358. // StateChanged(RAST_TSS_DIRTYBIT(j, D3DTSS_TEXTUREMAP));
  1359. }
  1360. }
  1361. }
  1362. }
  1363. bool NotCulled(LPD3DTLVERTEX pV0, LPD3DTLVERTEX pV1, LPD3DTLVERTEX pV2)
  1364. {
  1365. if (m_RastCtx.pdwRenderState[D3DRS_CULLMODE] == D3DCULL_NONE)
  1366. return true;
  1367. FLOAT x1, y1, x2x1, x3x1, y2y1, y3y1, fDet;
  1368. x1 = pV0->sx;
  1369. y1 = pV0->sy;
  1370. x2x1 = pV1->sx - x1;
  1371. y2y1 = pV1->sy - y1;
  1372. x3x1 = pV2->sx - x1;
  1373. y3y1 = pV2->sy - y1;
  1374. fDet = x2x1 * y3y1 - x3x1 * y2y1;
  1375. if (0. == fDet)
  1376. return false;
  1377. switch ( m_RastCtx.pdwRenderState[D3DRS_CULLMODE] )
  1378. {
  1379. case D3DCULL_CW:
  1380. if ( fDet > 0.f )
  1381. {
  1382. return false;
  1383. }
  1384. break;
  1385. case D3DCULL_CCW:
  1386. if ( fDet < 0.f )
  1387. {
  1388. return false;
  1389. }
  1390. break;
  1391. }
  1392. return true;
  1393. }
  1394. void DoDrawOnePrimitive( UINT16 FvfStride, PUINT8 pVtx,
  1395. D3DPRIMITIVETYPE PrimType, UINT cPrims)
  1396. {
  1397. INT i;
  1398. PUINT8 pV0, pV1, pV2;
  1399. HRESULT hr;
  1400. switch (PrimType)
  1401. {
  1402. case D3DPT_POINTLIST:
  1403. {
  1404. D3DVALUE fPointSize( GetRenderStateDV( D3DRS_POINTSIZE));
  1405. DWORD dwPScaleEn( GetRenderStateDW( D3DRS_POINTSCALEENABLE));
  1406. if( m_fvfData.offsetPSize!= 0 || fPointSize!= 1.0f ||
  1407. dwPScaleEn!= 0)
  1408. {
  1409. DWORD dwOldFill( GetRenderStateDW( D3DRS_FILLMODE));
  1410. DWORD dwOldShade( GetRenderStateDW( D3DRS_SHADEMODE));
  1411. DWORD dwOldCull( GetRenderStateDW( D3DRS_CULLMODE));
  1412. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  1413. dwOldCull!= D3DCULL_CCW)
  1414. {
  1415. End();
  1416. SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID);
  1417. SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT);
  1418. SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
  1419. Begin();
  1420. }
  1421. m_PrimProc.BeginPrimSet( D3DPT_TRIANGLELIST, m_fvfData.vtxType);
  1422. D3DHAL_DP2VIEWPORTINFO VInfo;
  1423. GetDP2ViewportInfo( VInfo);
  1424. D3DVALUE fPScaleA( GetRenderStateDV( D3DRS_POINTSCALE_A));
  1425. D3DVALUE fPScaleB( GetRenderStateDV( D3DRS_POINTSCALE_B));
  1426. D3DVALUE fPScaleC( GetRenderStateDV( D3DRS_POINTSCALE_C));
  1427. D3DVALUE fPSizeMax( GetRenderStateDV( D3DRS_POINTSIZE_MAX));
  1428. D3DVALUE fPSizeMin( GetRenderStateDV( D3DRS_POINTSIZE_MIN));
  1429. clamp( fPSizeMax, 0.0f,
  1430. CRGBDriver::GetCaps().MaxPointSize);
  1431. clamp( fPSizeMin, 0.0f, fPSizeMax);
  1432. for (i = (INT)cPrims; i > 0; i--)
  1433. {
  1434. if( m_fvfData.offsetPSize!= 0)
  1435. fPointSize= *reinterpret_cast<D3DVALUE*>
  1436. (pVtx+ m_fvfData.offsetPSize);
  1437. else
  1438. fPointSize= GetRenderStateDV( D3DRS_POINTSIZE);
  1439. if( dwPScaleEn)
  1440. {
  1441. D3DVALUE* pXYZ= reinterpret_cast< D3DVALUE*>(pVtx);
  1442. D3DVALUE De( sqrtf( pXYZ[0]* pXYZ[0]+
  1443. pXYZ[1]* pXYZ[1]+ pXYZ[2]* pXYZ[2]));
  1444. fPointSize*= VInfo.dwHeight* sqrtf( 1.0f/(
  1445. fPScaleA+ fPScaleB* De+ fPScaleC* De* De));
  1446. }
  1447. clamp( fPointSize, fPSizeMin, fPSizeMax);
  1448. fPointSize*= 0.5f;
  1449. RAST_GENERIC_VERTEX GV0, GV1, GV2, GV3;
  1450. PackGenVertex( pVtx, &GV0);
  1451. GV3= GV2= GV1= GV0;
  1452. GV0.sx-= fPointSize;
  1453. GV0.sy-= fPointSize;
  1454. GV1.sx+= fPointSize;
  1455. GV1.sy-= fPointSize;
  1456. GV2.sx+= fPointSize;
  1457. GV2.sy+= fPointSize;
  1458. GV3.sx-= fPointSize;
  1459. GV3.sy+= fPointSize;
  1460. if( GetRenderStateDV( D3DRS_POINTSPRITEENABLE)!= 0)
  1461. {
  1462. for( INT iT( 0); iT< m_fvfData.cActTex; iT++)
  1463. {
  1464. GV0.texCoord[iT].tu= 0.0f;
  1465. GV0.texCoord[iT].tv= 0.0f;
  1466. GV1.texCoord[iT].tu= 1.0f;
  1467. GV1.texCoord[iT].tv= 0.0f;
  1468. GV2.texCoord[iT].tu= 1.0f;
  1469. GV2.texCoord[iT].tv= 1.0f;
  1470. GV3.texCoord[iT].tu= 0.0f;
  1471. GV3.texCoord[iT].tv= 1.0f;
  1472. }
  1473. }
  1474. m_PrimProc.Tri(
  1475. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  1476. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1477. reinterpret_cast<D3DTLVERTEX*>(&GV2));
  1478. m_PrimProc.Tri(
  1479. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1480. reinterpret_cast<D3DTLVERTEX*>(&GV2),
  1481. reinterpret_cast<D3DTLVERTEX*>(&GV3));
  1482. pVtx += FvfStride;
  1483. }
  1484. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  1485. dwOldCull!= D3DCULL_CCW)
  1486. {
  1487. End();
  1488. SetRenderState( D3DRS_FILLMODE, dwOldFill);
  1489. SetRenderState( D3DRS_SHADEMODE, dwOldShade);
  1490. SetRenderState( D3DRS_CULLMODE, dwOldCull);
  1491. }
  1492. }
  1493. else
  1494. {
  1495. for (i = (INT)cPrims; i > 0; i--)
  1496. {
  1497. m_PrimProc.Point(
  1498. reinterpret_cast<D3DTLVERTEX*>(pVtx),
  1499. reinterpret_cast<D3DTLVERTEX*>(pVtx));
  1500. pVtx += FvfStride;
  1501. }
  1502. }
  1503. } break;
  1504. case D3DPT_LINELIST:
  1505. for (i = (INT)cPrims; i > 0; i--)
  1506. {
  1507. pV0 = pVtx;
  1508. pVtx += FvfStride;
  1509. pV1 = pVtx;
  1510. pVtx += FvfStride;
  1511. m_PrimProc.Line(
  1512. reinterpret_cast<D3DTLVERTEX*>(pV0),
  1513. reinterpret_cast<D3DTLVERTEX*>(pV1),
  1514. reinterpret_cast<D3DTLVERTEX*>(pV0));
  1515. }
  1516. break;
  1517. case D3DPT_LINESTRIP:
  1518. {
  1519. pV1 = pVtx;
  1520. // Disable last-pixel setting for shared verties and store prestate.
  1521. UINT uOldFlags= m_PrimProc.GetFlags();
  1522. m_PrimProc.ClrFlags(PPF_DRAW_LAST_LINE_PIXEL);
  1523. // Initial pV0.
  1524. for (i = (INT)cPrims; i > 1; i--)
  1525. {
  1526. pV0 = pV1;
  1527. pVtx += FvfStride;
  1528. pV1 = pVtx;
  1529. m_PrimProc.Line(
  1530. reinterpret_cast<D3DTLVERTEX*>(pV0),
  1531. reinterpret_cast<D3DTLVERTEX*>(pV1),
  1532. reinterpret_cast<D3DTLVERTEX*>(pV0));
  1533. }
  1534. // Restore last-pixel setting.
  1535. m_PrimProc.SetFlags(uOldFlags& PPF_DRAW_LAST_LINE_PIXEL);
  1536. // Draw last line with last-pixel setting from state.
  1537. if (i == 1)
  1538. {
  1539. pV0 = pVtx + FvfStride;
  1540. m_PrimProc.Line(
  1541. reinterpret_cast<D3DTLVERTEX*>(pV1),
  1542. reinterpret_cast<D3DTLVERTEX*>(pV0),
  1543. reinterpret_cast<D3DTLVERTEX*>(pV1));
  1544. }
  1545. }
  1546. break;
  1547. case D3DPT_TRIANGLELIST:
  1548. for (i = (INT)cPrims; i > 0; i--)
  1549. {
  1550. pV0 = pVtx;
  1551. pVtx += FvfStride;
  1552. pV1 = pVtx;
  1553. pVtx += FvfStride;
  1554. pV2 = pVtx;
  1555. pVtx += FvfStride;
  1556. // TODO: Move into PrimProc.
  1557. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1558. {
  1559. case D3DFILL_POINT:
  1560. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1561. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1562. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1563. break;
  1564. case D3DFILL_WIREFRAME:
  1565. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  1566. {
  1567. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1568. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1569. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1570. }
  1571. break;
  1572. case D3DFILL_SOLID:
  1573. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  1574. break;
  1575. }
  1576. }
  1577. break;
  1578. case D3DPT_TRIANGLESTRIP:
  1579. {
  1580. // Get initial vertex values.
  1581. pV1 = pVtx;
  1582. pVtx += FvfStride;
  1583. pV2 = pVtx;
  1584. pVtx += FvfStride;
  1585. for (i = (INT)cPrims; i > 1; i -= 2)
  1586. {
  1587. pV0 = pV1;
  1588. pV1 = pV2;
  1589. pV2 = pVtx;
  1590. pVtx += FvfStride;
  1591. // TODO: Move into PrimProc.
  1592. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1593. {
  1594. case D3DFILL_POINT:
  1595. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1596. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1597. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1598. break;
  1599. case D3DFILL_WIREFRAME:
  1600. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  1601. {
  1602. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1603. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1604. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1605. }
  1606. break;
  1607. case D3DFILL_SOLID:
  1608. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  1609. break;
  1610. }
  1611. pV0 = pV1;
  1612. pV1 = pV2;
  1613. pV2 = pVtx;
  1614. pVtx += FvfStride;
  1615. // TODO: Move into PrimProc.
  1616. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1617. {
  1618. case D3DFILL_POINT:
  1619. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1620. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1621. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1622. break;
  1623. case D3DFILL_WIREFRAME:
  1624. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV1))
  1625. {
  1626. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1627. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1628. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1629. }
  1630. break;
  1631. case D3DFILL_SOLID:
  1632. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV1);
  1633. break;
  1634. }
  1635. }
  1636. if (i > 0)
  1637. {
  1638. pV0 = pV1;
  1639. pV1 = pV2;
  1640. pV2 = pVtx;
  1641. // TODO: Move into PrimProc.
  1642. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1643. {
  1644. case D3DFILL_POINT:
  1645. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1646. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1647. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1648. break;
  1649. case D3DFILL_WIREFRAME:
  1650. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  1651. {
  1652. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1653. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1654. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1655. }
  1656. break;
  1657. case D3DFILL_SOLID:
  1658. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  1659. break;
  1660. }
  1661. }
  1662. }
  1663. break;
  1664. case D3DPT_TRIANGLEFAN:
  1665. {
  1666. pV2 = pVtx;
  1667. pVtx += FvfStride;
  1668. // Preload initial pV0.
  1669. pV1 = pVtx;
  1670. pVtx += FvfStride;
  1671. for (i = (INT)cPrims; i > 0; i--)
  1672. {
  1673. pV0 = pV1;
  1674. pV1 = pVtx;
  1675. pVtx += FvfStride;
  1676. // TODO: Move into PrimProc.
  1677. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1678. {
  1679. case D3DFILL_POINT:
  1680. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1681. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1682. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1683. break;
  1684. case D3DFILL_WIREFRAME:
  1685. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  1686. {
  1687. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  1688. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  1689. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  1690. }
  1691. break;
  1692. case D3DFILL_SOLID:
  1693. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  1694. break;
  1695. }
  1696. }
  1697. }
  1698. break;
  1699. default:
  1700. assert( false);
  1701. }
  1702. }
  1703. void DoDrawOneGenPrimitive( UINT16 FvfStride, PUINT8 pVtx,
  1704. D3DPRIMITIVETYPE PrimType, UINT cPrims)
  1705. {
  1706. INT i;
  1707. RAST_GENERIC_VERTEX GV0, GV1, GV2;
  1708. PUINT8 pV0, pV1, pV2;
  1709. HRESULT hr;
  1710. switch (PrimType)
  1711. {
  1712. case D3DPT_POINTLIST:
  1713. {
  1714. D3DVALUE fPointSize( GetRenderStateDV( D3DRS_POINTSIZE));
  1715. DWORD dwPScaleEn( GetRenderStateDW( D3DRS_POINTSCALEENABLE));
  1716. if( m_fvfData.offsetPSize!= 0 || fPointSize!= 1.0f ||
  1717. dwPScaleEn!= 0)
  1718. {
  1719. DWORD dwOldFill( GetRenderStateDW( D3DRS_FILLMODE));
  1720. DWORD dwOldShade( GetRenderStateDW( D3DRS_SHADEMODE));
  1721. DWORD dwOldCull( GetRenderStateDW( D3DRS_CULLMODE));
  1722. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  1723. dwOldCull!= D3DCULL_CCW)
  1724. {
  1725. End();
  1726. SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID);
  1727. SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT);
  1728. SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
  1729. Begin();
  1730. }
  1731. m_PrimProc.BeginPrimSet( D3DPT_TRIANGLELIST, m_fvfData.vtxType);
  1732. D3DHAL_DP2VIEWPORTINFO VInfo;
  1733. GetDP2ViewportInfo( VInfo);
  1734. D3DVALUE fPScaleA( GetRenderStateDV( D3DRS_POINTSCALE_A));
  1735. D3DVALUE fPScaleB( GetRenderStateDV( D3DRS_POINTSCALE_B));
  1736. D3DVALUE fPScaleC( GetRenderStateDV( D3DRS_POINTSCALE_C));
  1737. D3DVALUE fPSizeMax( GetRenderStateDV( D3DRS_POINTSIZE_MAX));
  1738. D3DVALUE fPSizeMin( GetRenderStateDV( D3DRS_POINTSIZE_MIN));
  1739. clamp( fPSizeMax, 0.0f,
  1740. CRGBDriver::GetCaps().MaxPointSize);
  1741. clamp( fPSizeMin, 0.0f, fPSizeMax);
  1742. for (i = (INT)cPrims; i > 0; i--)
  1743. {
  1744. if( m_fvfData.offsetPSize!= 0)
  1745. fPointSize= *reinterpret_cast<D3DVALUE*>
  1746. (pVtx+ m_fvfData.offsetPSize);
  1747. else
  1748. fPointSize= GetRenderStateDV( D3DRS_POINTSIZE);
  1749. if( dwPScaleEn)
  1750. {
  1751. D3DVALUE* pXYZ= reinterpret_cast< D3DVALUE*>(pVtx);
  1752. D3DVALUE De( sqrtf( pXYZ[0]* pXYZ[0]+
  1753. pXYZ[1]* pXYZ[1]+ pXYZ[2]* pXYZ[2]));
  1754. fPointSize*= VInfo.dwHeight* sqrtf( 1.0f/(
  1755. fPScaleA+ fPScaleB* De+ fPScaleC* De* De));
  1756. }
  1757. clamp( fPointSize, fPSizeMin, fPSizeMax);
  1758. fPointSize*= 0.5f;
  1759. RAST_GENERIC_VERTEX GV3;
  1760. PackGenVertex( pVtx, &GV0);
  1761. GV3= GV2= GV1= GV0;
  1762. GV0.sx-= fPointSize;
  1763. GV0.sy-= fPointSize;
  1764. GV1.sx+= fPointSize;
  1765. GV1.sy-= fPointSize;
  1766. GV2.sx+= fPointSize;
  1767. GV2.sy+= fPointSize;
  1768. GV3.sx-= fPointSize;
  1769. GV3.sy+= fPointSize;
  1770. if( GetRenderStateDV( D3DRS_POINTSPRITEENABLE)!= 0)
  1771. {
  1772. for( INT iT( 0); iT< m_fvfData.cActTex; iT++)
  1773. {
  1774. GV0.texCoord[iT].tu= 0.0f;
  1775. GV0.texCoord[iT].tv= 0.0f;
  1776. GV1.texCoord[iT].tu= 1.0f;
  1777. GV1.texCoord[iT].tv= 0.0f;
  1778. GV2.texCoord[iT].tu= 1.0f;
  1779. GV2.texCoord[iT].tv= 1.0f;
  1780. GV3.texCoord[iT].tu= 0.0f;
  1781. GV3.texCoord[iT].tv= 1.0f;
  1782. }
  1783. }
  1784. m_PrimProc.Tri(
  1785. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  1786. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1787. reinterpret_cast<D3DTLVERTEX*>(&GV2));
  1788. m_PrimProc.Tri(
  1789. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1790. reinterpret_cast<D3DTLVERTEX*>(&GV2),
  1791. reinterpret_cast<D3DTLVERTEX*>(&GV3));
  1792. pVtx += FvfStride;
  1793. }
  1794. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  1795. dwOldCull!= D3DCULL_CCW)
  1796. {
  1797. End();
  1798. SetRenderState( D3DRS_FILLMODE, dwOldFill);
  1799. SetRenderState( D3DRS_SHADEMODE, dwOldShade);
  1800. SetRenderState( D3DRS_CULLMODE, dwOldCull);
  1801. }
  1802. }
  1803. else
  1804. {
  1805. for (i = (INT)cPrims; i > 0; i--)
  1806. {
  1807. PackGenVertex( pVtx, &GV0);
  1808. m_PrimProc.Point(
  1809. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  1810. reinterpret_cast<D3DTLVERTEX*>(&GV0));
  1811. pVtx += FvfStride;
  1812. }
  1813. }
  1814. } break;
  1815. case D3DPT_LINELIST:
  1816. for (i = (INT)cPrims; i > 0; i--)
  1817. {
  1818. pV0 = pVtx;
  1819. pVtx += FvfStride;
  1820. pV1 = pVtx;
  1821. pVtx += FvfStride;
  1822. PackGenVertex( pV0, &GV0);
  1823. PackGenVertex( pV1, &GV1);
  1824. m_PrimProc.Line(
  1825. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  1826. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1827. reinterpret_cast<D3DTLVERTEX*>(&GV0));
  1828. }
  1829. break;
  1830. case D3DPT_LINESTRIP:
  1831. {
  1832. pV1 = pVtx;
  1833. PackGenVertex( pV1, &GV1);
  1834. // Disable last-pixel setting for shared verties and store prestate.
  1835. UINT uOldFlags= m_PrimProc.GetFlags();
  1836. m_PrimProc.ClrFlags(PPF_DRAW_LAST_LINE_PIXEL);
  1837. // Initial pV0.
  1838. for (i = (INT)cPrims; i > 1; i--)
  1839. {
  1840. pV0 = pV1;
  1841. GV0= GV1;
  1842. pVtx += FvfStride;
  1843. pV1 = pVtx;
  1844. PackGenVertex( pV1, &GV1);
  1845. m_PrimProc.Line(
  1846. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  1847. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1848. reinterpret_cast<D3DTLVERTEX*>(&GV0));
  1849. }
  1850. // Restore last-pixel setting.
  1851. m_PrimProc.SetFlags(uOldFlags& PPF_DRAW_LAST_LINE_PIXEL);
  1852. // Draw last line with last-pixel setting from state.
  1853. if (i == 1)
  1854. {
  1855. pV0 = pVtx + FvfStride;
  1856. PackGenVertex( pV0, &GV0);
  1857. m_PrimProc.Line(
  1858. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  1859. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  1860. reinterpret_cast<D3DTLVERTEX*>(&GV1));
  1861. }
  1862. }
  1863. break;
  1864. case D3DPT_TRIANGLELIST:
  1865. for (i = (INT)cPrims; i > 0; i--)
  1866. {
  1867. pV0 = pVtx;
  1868. pVtx += FvfStride;
  1869. pV1 = pVtx;
  1870. pVtx += FvfStride;
  1871. pV2 = pVtx;
  1872. pVtx += FvfStride;
  1873. PackGenVertex( pV0, &GV0);
  1874. PackGenVertex( pV1, &GV1);
  1875. PackGenVertex( pV2, &GV2);
  1876. // TODO: Move into PrimProc.
  1877. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1878. {
  1879. case D3DFILL_POINT:
  1880. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1881. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1882. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1883. break;
  1884. case D3DFILL_WIREFRAME:
  1885. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  1886. {
  1887. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1888. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1889. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1890. }
  1891. break;
  1892. case D3DFILL_SOLID:
  1893. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  1894. break;
  1895. }
  1896. }
  1897. break;
  1898. case D3DPT_TRIANGLESTRIP:
  1899. {
  1900. // Get initial vertex values.
  1901. pV1 = pVtx;
  1902. pVtx += FvfStride;
  1903. pV2 = pVtx;
  1904. pVtx += FvfStride;
  1905. PackGenVertex( pV1, &GV1);
  1906. PackGenVertex( pV2, &GV2);
  1907. for (i = (INT)cPrims; i > 1; i -= 2)
  1908. {
  1909. pV0 = pV1;
  1910. GV0 = GV1;
  1911. pV1 = pV2;
  1912. GV1 = GV2;
  1913. pV2 = pVtx;
  1914. PackGenVertex( pV2, &GV2);
  1915. pVtx += FvfStride;
  1916. // TODO: Move into PrimProc.
  1917. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1918. {
  1919. case D3DFILL_POINT:
  1920. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1921. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1922. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1923. break;
  1924. case D3DFILL_WIREFRAME:
  1925. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  1926. {
  1927. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1928. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1929. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1930. }
  1931. break;
  1932. case D3DFILL_SOLID:
  1933. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  1934. break;
  1935. }
  1936. pV0 = pV1;
  1937. GV0 = GV1;
  1938. pV1 = pV2;
  1939. GV1 = GV2;
  1940. pV2 = pVtx;
  1941. PackGenVertex( pV2, &GV2);
  1942. pVtx += FvfStride;
  1943. // TODO: Move into PrimProc.
  1944. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1945. {
  1946. case D3DFILL_POINT:
  1947. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1948. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1949. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1950. break;
  1951. case D3DFILL_WIREFRAME:
  1952. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV1))
  1953. {
  1954. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1955. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1956. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1957. }
  1958. break;
  1959. case D3DFILL_SOLID:
  1960. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV1);
  1961. break;
  1962. }
  1963. }
  1964. if (i > 0)
  1965. {
  1966. pV0 = pV1;
  1967. GV0 = GV1;
  1968. pV1 = pV2;
  1969. GV1 = GV2;
  1970. pV2 = pVtx;
  1971. PackGenVertex( pV2, &GV2);
  1972. // TODO: Move into PrimProc.
  1973. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  1974. {
  1975. case D3DFILL_POINT:
  1976. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1977. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1978. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1979. break;
  1980. case D3DFILL_WIREFRAME:
  1981. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  1982. {
  1983. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  1984. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  1985. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  1986. }
  1987. break;
  1988. case D3DFILL_SOLID:
  1989. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  1990. break;
  1991. }
  1992. }
  1993. }
  1994. break;
  1995. case D3DPT_TRIANGLEFAN:
  1996. {
  1997. pV2 = pVtx;
  1998. PackGenVertex( pV2, &GV2);
  1999. pVtx += FvfStride;
  2000. // Preload initial pV0.
  2001. pV1 = pVtx;
  2002. PackGenVertex( pV1, &GV1);
  2003. pVtx += FvfStride;
  2004. for (i = (INT)cPrims; i > 0; i--)
  2005. {
  2006. pV0 = pV1;
  2007. GV0 = GV1;
  2008. pV1 = pVtx;
  2009. PackGenVertex( pV1, &GV1);
  2010. pVtx += FvfStride;
  2011. // TODO: Move into PrimProc.
  2012. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2013. {
  2014. case D3DFILL_POINT:
  2015. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2016. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2017. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2018. break;
  2019. case D3DFILL_WIREFRAME:
  2020. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2021. {
  2022. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2023. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2024. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2025. }
  2026. break;
  2027. case D3DFILL_SOLID:
  2028. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2029. break;
  2030. }
  2031. }
  2032. }
  2033. break;
  2034. default:
  2035. assert( false);
  2036. }
  2037. }
  2038. void DoDrawOneIndexedPrimitive( UINT16 FvfStride, PUINT8 pVtx,
  2039. LPWORD puIndices, D3DPRIMITIVETYPE PrimType, UINT cPrims)
  2040. {
  2041. INT i;
  2042. PUINT8 pV0, pV1, pV2;
  2043. HRESULT hr;
  2044. switch(PrimType)
  2045. {
  2046. case D3DPT_POINTLIST:
  2047. {
  2048. D3DVALUE fPointSize( GetRenderStateDV( D3DRS_POINTSIZE));
  2049. DWORD dwPScaleEn( GetRenderStateDW( D3DRS_POINTSCALEENABLE));
  2050. if( m_fvfData.offsetPSize!= 0 || fPointSize!= 1.0f ||
  2051. dwPScaleEn!= 0)
  2052. {
  2053. DWORD dwOldFill( GetRenderStateDW( D3DRS_FILLMODE));
  2054. DWORD dwOldShade( GetRenderStateDW( D3DRS_SHADEMODE));
  2055. DWORD dwOldCull( GetRenderStateDW( D3DRS_CULLMODE));
  2056. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  2057. dwOldCull!= D3DCULL_CCW)
  2058. {
  2059. End();
  2060. SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID);
  2061. SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT);
  2062. SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
  2063. Begin();
  2064. }
  2065. m_PrimProc.BeginPrimSet( D3DPT_TRIANGLELIST, m_fvfData.vtxType);
  2066. D3DHAL_DP2VIEWPORTINFO VInfo;
  2067. GetDP2ViewportInfo( VInfo);
  2068. D3DVALUE fPScaleA( GetRenderStateDV( D3DRS_POINTSCALE_A));
  2069. D3DVALUE fPScaleB( GetRenderStateDV( D3DRS_POINTSCALE_B));
  2070. D3DVALUE fPScaleC( GetRenderStateDV( D3DRS_POINTSCALE_C));
  2071. D3DVALUE fPSizeMax( GetRenderStateDV( D3DRS_POINTSIZE_MAX));
  2072. D3DVALUE fPSizeMin( GetRenderStateDV( D3DRS_POINTSIZE_MIN));
  2073. clamp( fPSizeMax, 0.0f,
  2074. CRGBDriver::GetCaps().MaxPointSize);
  2075. clamp( fPSizeMin, 0.0f, fPSizeMax);
  2076. for (i = (INT)cPrims; i > 0; i--)
  2077. {
  2078. if( m_fvfData.offsetPSize!= 0)
  2079. fPointSize= *reinterpret_cast<D3DVALUE*>
  2080. (pVtx+ m_fvfData.offsetPSize);
  2081. else
  2082. fPointSize= GetRenderStateDV( D3DRS_POINTSIZE);
  2083. if( dwPScaleEn)
  2084. {
  2085. D3DVALUE* pXYZ= reinterpret_cast< D3DVALUE*>(pVtx);
  2086. D3DVALUE De( sqrtf( pXYZ[0]* pXYZ[0]+
  2087. pXYZ[1]* pXYZ[1]+ pXYZ[2]* pXYZ[2]));
  2088. fPointSize*= VInfo.dwHeight* sqrtf( 1.0f/(
  2089. fPScaleA+ fPScaleB* De+ fPScaleC* De* De));
  2090. }
  2091. clamp( fPointSize, fPSizeMin, fPSizeMax);
  2092. fPointSize*= 0.5f;
  2093. RAST_GENERIC_VERTEX GV0, GV1, GV2, GV3;
  2094. pV0 = pVtx + FvfStride * (*puIndices++);
  2095. PackGenVertex( pV0, &GV0);
  2096. GV3= GV2= GV1= GV0;
  2097. GV0.sx-= fPointSize;
  2098. GV0.sy-= fPointSize;
  2099. GV1.sx+= fPointSize;
  2100. GV1.sy-= fPointSize;
  2101. GV2.sx+= fPointSize;
  2102. GV2.sy+= fPointSize;
  2103. GV3.sx-= fPointSize;
  2104. GV3.sy+= fPointSize;
  2105. if( GetRenderStateDV( D3DRS_POINTSPRITEENABLE)!= 0)
  2106. {
  2107. for( INT iT( 0); iT< m_fvfData.cActTex; iT++)
  2108. {
  2109. GV0.texCoord[iT].tu= 0.0f;
  2110. GV0.texCoord[iT].tv= 0.0f;
  2111. GV1.texCoord[iT].tu= 1.0f;
  2112. GV1.texCoord[iT].tv= 0.0f;
  2113. GV2.texCoord[iT].tu= 1.0f;
  2114. GV2.texCoord[iT].tv= 1.0f;
  2115. GV3.texCoord[iT].tu= 0.0f;
  2116. GV3.texCoord[iT].tv= 1.0f;
  2117. }
  2118. }
  2119. m_PrimProc.Tri(
  2120. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  2121. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2122. reinterpret_cast<D3DTLVERTEX*>(&GV2));
  2123. m_PrimProc.Tri(
  2124. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2125. reinterpret_cast<D3DTLVERTEX*>(&GV2),
  2126. reinterpret_cast<D3DTLVERTEX*>(&GV3));
  2127. pVtx += FvfStride;
  2128. }
  2129. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  2130. dwOldCull!= D3DCULL_CCW)
  2131. {
  2132. End();
  2133. SetRenderState( D3DRS_FILLMODE, dwOldFill);
  2134. SetRenderState( D3DRS_SHADEMODE, dwOldShade);
  2135. SetRenderState( D3DRS_CULLMODE, dwOldCull);
  2136. }
  2137. }
  2138. else
  2139. {
  2140. for (i = (INT)cPrims; i > 0; i--)
  2141. {
  2142. pV0 = pVtx + FvfStride * (*puIndices++);
  2143. m_PrimProc.Point(
  2144. reinterpret_cast<D3DTLVERTEX*>(pV0),
  2145. reinterpret_cast<D3DTLVERTEX*>(pV0));
  2146. }
  2147. }
  2148. } break;
  2149. case D3DPT_LINELIST:
  2150. for (i = (INT)cPrims; i > 0; i--)
  2151. {
  2152. pV0 = pVtx + FvfStride * (*puIndices++);
  2153. pV1 = pVtx + FvfStride * (*puIndices++);
  2154. m_PrimProc.Line(
  2155. reinterpret_cast<D3DTLVERTEX*>(pV0),
  2156. reinterpret_cast<D3DTLVERTEX*>(pV1),
  2157. reinterpret_cast<D3DTLVERTEX*>(pV0));
  2158. }
  2159. break;
  2160. case D3DPT_LINESTRIP:
  2161. {
  2162. // Disable last-pixel setting for shared verties and store prestate.
  2163. UINT uOldFlags= m_PrimProc.GetFlags();
  2164. m_PrimProc.ClrFlags(PPF_DRAW_LAST_LINE_PIXEL);
  2165. // Initial pV1.
  2166. pV1 = pVtx + FvfStride * (*puIndices++);
  2167. for (i = (INT)cPrims; i > 1; i--)
  2168. {
  2169. pV0 = pV1;
  2170. pV1 = pVtx + FvfStride * (*puIndices++);
  2171. m_PrimProc.Line(
  2172. reinterpret_cast<D3DTLVERTEX*>(pV0),
  2173. reinterpret_cast<D3DTLVERTEX*>(pV1),
  2174. reinterpret_cast<D3DTLVERTEX*>(pV0));
  2175. }
  2176. // Restore last-pixel setting.
  2177. m_PrimProc.SetFlags(uOldFlags& PPF_DRAW_LAST_LINE_PIXEL);
  2178. // Draw last line with last-pixel setting from state.
  2179. if (i == 1)
  2180. {
  2181. pV0 = pVtx + FvfStride * (*puIndices);
  2182. m_PrimProc.Line(
  2183. reinterpret_cast<D3DTLVERTEX*>(pV1),
  2184. reinterpret_cast<D3DTLVERTEX*>(pV0),
  2185. reinterpret_cast<D3DTLVERTEX*>(pV1));
  2186. }
  2187. }
  2188. break;
  2189. case D3DPT_TRIANGLELIST:
  2190. for (i = (INT)cPrims; i > 0; i--)
  2191. {
  2192. pV0 = pVtx + FvfStride * (*puIndices++);
  2193. pV1 = pVtx + FvfStride * (*puIndices++);
  2194. pV2 = pVtx + FvfStride * (*puIndices++);
  2195. // TODO: Move into PrimProc.
  2196. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2197. {
  2198. case D3DFILL_POINT:
  2199. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2200. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2201. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2202. break;
  2203. case D3DFILL_WIREFRAME:
  2204. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2205. {
  2206. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2207. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2208. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2209. }
  2210. break;
  2211. case D3DFILL_SOLID:
  2212. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2213. break;
  2214. }
  2215. }
  2216. break;
  2217. case D3DPT_TRIANGLESTRIP:
  2218. {
  2219. // Get initial vertex values.
  2220. pV1 = pVtx + FvfStride * (*puIndices++);
  2221. pV2 = pVtx + FvfStride * (*puIndices++);
  2222. for (i = (INT)cPrims; i > 1; i-= 2)
  2223. {
  2224. pV0 = pV1;
  2225. pV1 = pV2;
  2226. pV2 = pVtx + FvfStride * (*puIndices++);
  2227. // TODO: Move into PrimProc.
  2228. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2229. {
  2230. case D3DFILL_POINT:
  2231. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2232. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2233. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2234. break;
  2235. case D3DFILL_WIREFRAME:
  2236. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2237. {
  2238. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2239. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2240. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2241. }
  2242. break;
  2243. case D3DFILL_SOLID:
  2244. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2245. break;
  2246. }
  2247. pV0 = pV1;
  2248. pV1 = pV2;
  2249. pV2 = pVtx + FvfStride * (*puIndices++);
  2250. // TODO: Move into PrimProc.
  2251. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2252. {
  2253. case D3DFILL_POINT:
  2254. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2255. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2256. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2257. break;
  2258. case D3DFILL_WIREFRAME:
  2259. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV1))
  2260. {
  2261. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2262. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2263. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2264. }
  2265. break;
  2266. case D3DFILL_SOLID:
  2267. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV1);
  2268. break;
  2269. }
  2270. }
  2271. if (i > 0)
  2272. {
  2273. pV0 = pV1;
  2274. pV1 = pV2;
  2275. pV2 = pVtx + FvfStride * (*puIndices++);
  2276. // TODO: Move into PrimProc.
  2277. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2278. {
  2279. case D3DFILL_POINT:
  2280. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2281. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2282. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2283. break;
  2284. case D3DFILL_WIREFRAME:
  2285. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2286. {
  2287. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2288. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2289. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2290. }
  2291. break;
  2292. case D3DFILL_SOLID:
  2293. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2294. break;
  2295. }
  2296. }
  2297. }
  2298. break;
  2299. case D3DPT_TRIANGLEFAN:
  2300. {
  2301. pV2 = pVtx + FvfStride * (*puIndices++);
  2302. // Preload initial pV0.
  2303. pV1 = pVtx + FvfStride * (*puIndices++);
  2304. for (i = (INT)cPrims; i > 0; i--)
  2305. {
  2306. pV0 = pV1;
  2307. pV1 = pVtx + FvfStride * (*puIndices++);
  2308. // TODO: Move into PrimProc.
  2309. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2310. {
  2311. case D3DFILL_POINT:
  2312. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2313. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2314. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2315. break;
  2316. case D3DFILL_WIREFRAME:
  2317. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2318. {
  2319. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2320. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2321. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2322. }
  2323. break;
  2324. case D3DFILL_SOLID:
  2325. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2326. break;
  2327. }
  2328. }
  2329. }
  2330. break;
  2331. }
  2332. }
  2333. void DoDrawOneGenIndexedPrimitive( UINT16 FvfStride, PUINT8 pVtx,
  2334. LPWORD puIndices, D3DPRIMITIVETYPE PrimType, UINT cPrims)
  2335. {
  2336. INT i;
  2337. RAST_GENERIC_VERTEX GV0, GV1, GV2;
  2338. PUINT8 pV0, pV1, pV2;
  2339. HRESULT hr;
  2340. switch(PrimType)
  2341. {
  2342. case D3DPT_POINTLIST:
  2343. {
  2344. D3DVALUE fPointSize( GetRenderStateDV( D3DRS_POINTSIZE));
  2345. DWORD dwPScaleEn( GetRenderStateDW( D3DRS_POINTSCALEENABLE));
  2346. if( m_fvfData.offsetPSize!= 0 || fPointSize!= 1.0f ||
  2347. dwPScaleEn!= 0)
  2348. {
  2349. DWORD dwOldFill( GetRenderStateDW( D3DRS_FILLMODE));
  2350. DWORD dwOldShade( GetRenderStateDW( D3DRS_SHADEMODE));
  2351. DWORD dwOldCull( GetRenderStateDW( D3DRS_CULLMODE));
  2352. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  2353. dwOldCull!= D3DCULL_CCW)
  2354. {
  2355. End();
  2356. SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID);
  2357. SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT);
  2358. SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
  2359. Begin();
  2360. }
  2361. m_PrimProc.BeginPrimSet( D3DPT_TRIANGLELIST, m_fvfData.vtxType);
  2362. D3DHAL_DP2VIEWPORTINFO VInfo;
  2363. GetDP2ViewportInfo( VInfo);
  2364. D3DVALUE fPScaleA( GetRenderStateDV( D3DRS_POINTSCALE_A));
  2365. D3DVALUE fPScaleB( GetRenderStateDV( D3DRS_POINTSCALE_B));
  2366. D3DVALUE fPScaleC( GetRenderStateDV( D3DRS_POINTSCALE_C));
  2367. D3DVALUE fPSizeMax( GetRenderStateDV( D3DRS_POINTSIZE_MAX));
  2368. D3DVALUE fPSizeMin( GetRenderStateDV( D3DRS_POINTSIZE_MIN));
  2369. clamp( fPSizeMax, 0.0f,
  2370. CRGBDriver::GetCaps().MaxPointSize);
  2371. clamp( fPSizeMin, 0.0f, fPSizeMax);
  2372. for (i = (INT)cPrims; i > 0; i--)
  2373. {
  2374. if( m_fvfData.offsetPSize!= 0)
  2375. fPointSize= *reinterpret_cast<D3DVALUE*>
  2376. (pVtx+ m_fvfData.offsetPSize);
  2377. else
  2378. fPointSize= GetRenderStateDV( D3DRS_POINTSIZE);
  2379. if( dwPScaleEn)
  2380. {
  2381. D3DVALUE* pXYZ= reinterpret_cast< D3DVALUE*>(pVtx);
  2382. D3DVALUE De( sqrtf( pXYZ[0]* pXYZ[0]+
  2383. pXYZ[1]* pXYZ[1]+ pXYZ[2]* pXYZ[2]));
  2384. fPointSize*= VInfo.dwHeight* sqrtf( 1.0f/(
  2385. fPScaleA+ fPScaleB* De+ fPScaleC* De* De));
  2386. }
  2387. clamp( fPointSize, fPSizeMin, fPSizeMax);
  2388. fPointSize*= 0.5f;
  2389. RAST_GENERIC_VERTEX GV3;
  2390. pV0 = pVtx + FvfStride * (*puIndices++);
  2391. PackGenVertex( pV0, &GV0);
  2392. GV3= GV2= GV1= GV0;
  2393. GV0.sx-= fPointSize;
  2394. GV0.sy-= fPointSize;
  2395. GV1.sx+= fPointSize;
  2396. GV1.sy-= fPointSize;
  2397. GV2.sx+= fPointSize;
  2398. GV2.sy+= fPointSize;
  2399. GV3.sx-= fPointSize;
  2400. GV3.sy+= fPointSize;
  2401. if( GetRenderStateDV( D3DRS_POINTSPRITEENABLE)!= 0)
  2402. {
  2403. for( INT iT( 0); iT< m_fvfData.cActTex; iT++)
  2404. {
  2405. GV0.texCoord[iT].tu= 0.0f;
  2406. GV0.texCoord[iT].tv= 0.0f;
  2407. GV1.texCoord[iT].tu= 1.0f;
  2408. GV1.texCoord[iT].tv= 0.0f;
  2409. GV2.texCoord[iT].tu= 1.0f;
  2410. GV2.texCoord[iT].tv= 1.0f;
  2411. GV3.texCoord[iT].tu= 0.0f;
  2412. GV3.texCoord[iT].tv= 1.0f;
  2413. }
  2414. }
  2415. m_PrimProc.Tri(
  2416. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  2417. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2418. reinterpret_cast<D3DTLVERTEX*>(&GV2));
  2419. m_PrimProc.Tri(
  2420. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2421. reinterpret_cast<D3DTLVERTEX*>(&GV2),
  2422. reinterpret_cast<D3DTLVERTEX*>(&GV3));
  2423. pVtx += FvfStride;
  2424. }
  2425. if( dwOldFill!= D3DFILL_SOLID || dwOldShade!= D3DSHADE_FLAT ||
  2426. dwOldCull!= D3DCULL_CCW)
  2427. {
  2428. End();
  2429. SetRenderState( D3DRS_FILLMODE, dwOldFill);
  2430. SetRenderState( D3DRS_SHADEMODE, dwOldShade);
  2431. SetRenderState( D3DRS_CULLMODE, dwOldCull);
  2432. }
  2433. }
  2434. else
  2435. {
  2436. for (i = (INT)cPrims; i > 0; i--)
  2437. {
  2438. pV0 = pVtx + FvfStride * (*puIndices++);
  2439. PackGenVertex( pV0, &GV0);
  2440. m_PrimProc.Point(
  2441. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  2442. reinterpret_cast<D3DTLVERTEX*>(&GV0));
  2443. }
  2444. }
  2445. } break;
  2446. case D3DPT_LINELIST:
  2447. for (i = (INT)cPrims; i > 0; i--)
  2448. {
  2449. pV0 = pVtx + FvfStride * (*puIndices++);
  2450. PackGenVertex( pV0, &GV0);
  2451. pV1 = pVtx + FvfStride * (*puIndices++);
  2452. PackGenVertex( pV1, &GV1);
  2453. m_PrimProc.Line(
  2454. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  2455. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2456. reinterpret_cast<D3DTLVERTEX*>(&GV0));
  2457. }
  2458. break;
  2459. case D3DPT_LINESTRIP:
  2460. {
  2461. // Disable last-pixel setting for shared verties and store prestate.
  2462. UINT uOldFlags= m_PrimProc.GetFlags();
  2463. m_PrimProc.ClrFlags(PPF_DRAW_LAST_LINE_PIXEL);
  2464. // Initial pV1.
  2465. pV1 = pVtx + FvfStride * (*puIndices++);
  2466. PackGenVertex( pV1, &GV1);
  2467. for (i = (INT)cPrims; i > 1; i--)
  2468. {
  2469. pV0 = pV1;
  2470. GV0 = GV1;
  2471. pV1 = pVtx + FvfStride * (*puIndices++);
  2472. PackGenVertex( pV1, &GV1);
  2473. m_PrimProc.Line(
  2474. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  2475. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2476. reinterpret_cast<D3DTLVERTEX*>(&GV0));
  2477. }
  2478. // Restore last-pixel setting.
  2479. m_PrimProc.SetFlags(uOldFlags& PPF_DRAW_LAST_LINE_PIXEL);
  2480. // Draw last line with last-pixel setting from state.
  2481. if (i == 1)
  2482. {
  2483. pV0 = pVtx + FvfStride * (*puIndices);
  2484. PackGenVertex( pV0, &GV0);
  2485. m_PrimProc.Line(
  2486. reinterpret_cast<D3DTLVERTEX*>(&GV1),
  2487. reinterpret_cast<D3DTLVERTEX*>(&GV0),
  2488. reinterpret_cast<D3DTLVERTEX*>(&GV1));
  2489. }
  2490. }
  2491. break;
  2492. case D3DPT_TRIANGLELIST:
  2493. for (i = (INT)cPrims; i > 0; i--)
  2494. {
  2495. pV0 = pVtx + FvfStride * (*puIndices++);
  2496. PackGenVertex( pV0, &GV0);
  2497. pV1 = pVtx + FvfStride * (*puIndices++);
  2498. PackGenVertex( pV1, &GV1);
  2499. pV2 = pVtx + FvfStride * (*puIndices++);
  2500. PackGenVertex( pV2, &GV2);
  2501. // TODO: Move into PrimProc.
  2502. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2503. {
  2504. case D3DFILL_POINT:
  2505. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2506. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2507. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2508. break;
  2509. case D3DFILL_WIREFRAME:
  2510. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2511. {
  2512. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2513. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2514. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2515. }
  2516. break;
  2517. case D3DFILL_SOLID:
  2518. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2519. break;
  2520. }
  2521. }
  2522. break;
  2523. case D3DPT_TRIANGLESTRIP:
  2524. {
  2525. // Get initial vertex values.
  2526. pV1 = pVtx + FvfStride * (*puIndices++);
  2527. PackGenVertex( pV1, &GV1);
  2528. pV2 = pVtx + FvfStride * (*puIndices++);
  2529. PackGenVertex( pV2, &GV2);
  2530. for (i = (INT)cPrims; i > 1; i-= 2)
  2531. {
  2532. pV0 = pV1;
  2533. GV0 = GV1;
  2534. pV1 = pV2;
  2535. GV1 = GV2;
  2536. pV2 = pVtx + FvfStride * (*puIndices++);
  2537. PackGenVertex( pV2, &GV2);
  2538. // TODO: Move into PrimProc.
  2539. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2540. {
  2541. case D3DFILL_POINT:
  2542. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2543. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2544. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2545. break;
  2546. case D3DFILL_WIREFRAME:
  2547. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2548. {
  2549. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2550. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2551. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2552. }
  2553. break;
  2554. case D3DFILL_SOLID:
  2555. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2556. break;
  2557. }
  2558. pV0 = pV1;
  2559. GV0 = GV1;
  2560. pV1 = pV2;
  2561. GV1 = GV2;
  2562. pV2 = pVtx + FvfStride * (*puIndices++);
  2563. PackGenVertex( pV2, &GV2);
  2564. // TODO: Move into PrimProc.
  2565. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2566. {
  2567. case D3DFILL_POINT:
  2568. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2569. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2570. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2571. break;
  2572. case D3DFILL_WIREFRAME:
  2573. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV1))
  2574. {
  2575. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2576. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2577. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2578. }
  2579. break;
  2580. case D3DFILL_SOLID:
  2581. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV1);
  2582. break;
  2583. }
  2584. }
  2585. if (i > 0)
  2586. {
  2587. pV0 = pV1;
  2588. GV0 = GV1;
  2589. pV1 = pV2;
  2590. GV1 = GV2;
  2591. pV2 = pVtx + FvfStride * (*puIndices++);
  2592. PackGenVertex( pV2, &GV2);
  2593. // TODO: Move into PrimProc.
  2594. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2595. {
  2596. case D3DFILL_POINT:
  2597. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2598. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2599. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2600. break;
  2601. case D3DFILL_WIREFRAME:
  2602. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2603. {
  2604. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2605. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2606. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2607. }
  2608. break;
  2609. case D3DFILL_SOLID:
  2610. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2611. break;
  2612. }
  2613. }
  2614. }
  2615. break;
  2616. case D3DPT_TRIANGLEFAN:
  2617. {
  2618. pV2 = pVtx + FvfStride * (*puIndices++);
  2619. PackGenVertex( pV2, &GV2);
  2620. // Preload initial pV0.
  2621. pV1 = pVtx + FvfStride * (*puIndices++);
  2622. PackGenVertex( pV1, &GV1);
  2623. for (i = (INT)cPrims; i > 0; i--)
  2624. {
  2625. pV0 = pV1;
  2626. GV0 = GV1;
  2627. pV1 = pVtx + FvfStride * (*puIndices++);
  2628. PackGenVertex( pV1, &GV1);
  2629. // TODO: Move into PrimProc.
  2630. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2631. {
  2632. case D3DFILL_POINT:
  2633. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2634. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2635. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2636. break;
  2637. case D3DFILL_WIREFRAME:
  2638. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2639. {
  2640. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2641. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2642. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2643. }
  2644. break;
  2645. case D3DFILL_SOLID:
  2646. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2647. break;
  2648. }
  2649. }
  2650. }
  2651. break;
  2652. }
  2653. }
  2654. void DoDrawOneEdgeFlagTriangleFan( UINT16 FvfStride, PUINT8 pVtx,
  2655. UINT cPrims, UINT32 dwEdgeFlags)
  2656. {
  2657. INT i;
  2658. PUINT8 pV0, pV1, pV2;
  2659. HRESULT hr;
  2660. pV2 = pVtx;
  2661. pVtx += FvfStride;
  2662. pV0 = pVtx;
  2663. pVtx += FvfStride;
  2664. pV1 = pVtx;
  2665. pVtx += FvfStride;
  2666. WORD wFlags = 0;
  2667. if(dwEdgeFlags & 0x2)
  2668. wFlags |= D3DTRIFLAG_EDGEENABLE1;
  2669. if(dwEdgeFlags & 0x1)
  2670. wFlags |= D3DTRIFLAG_EDGEENABLE3;
  2671. if(cPrims == 1) {
  2672. if(dwEdgeFlags & 0x4)
  2673. wFlags |= D3DTRIFLAG_EDGEENABLE2;
  2674. // TODO: Move into PrimProc.
  2675. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2676. {
  2677. case D3DFILL_POINT:
  2678. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2679. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2680. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2681. break;
  2682. case D3DFILL_WIREFRAME:
  2683. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2684. {
  2685. if( wFlags& D3DTRIFLAG_EDGEENABLE1)
  2686. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2687. if( wFlags& D3DTRIFLAG_EDGEENABLE2)
  2688. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2689. if( wFlags& D3DTRIFLAG_EDGEENABLE3)
  2690. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2691. }
  2692. break;
  2693. case D3DFILL_SOLID:
  2694. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2695. break;
  2696. }
  2697. return;
  2698. }
  2699. // TODO: Move into PrimProc.
  2700. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2701. {
  2702. case D3DFILL_POINT:
  2703. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2704. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2705. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2706. break;
  2707. case D3DFILL_WIREFRAME:
  2708. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2709. {
  2710. if( wFlags& D3DTRIFLAG_EDGEENABLE1)
  2711. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2712. if( wFlags& D3DTRIFLAG_EDGEENABLE2)
  2713. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2714. if( wFlags& D3DTRIFLAG_EDGEENABLE3)
  2715. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2716. }
  2717. break;
  2718. case D3DFILL_SOLID:
  2719. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2720. break;
  2721. }
  2722. UINT32 dwMask = 0x4;
  2723. for (i = (INT)cPrims - 2; i > 0; i--)
  2724. {
  2725. pV0 = pV1;
  2726. pV1 = pVtx;
  2727. pVtx += FvfStride;
  2728. if(true|| (dwEdgeFlags & dwMask)!= 0)
  2729. {
  2730. // TODO: Move into PrimProc.
  2731. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2732. {
  2733. case D3DFILL_POINT:
  2734. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2735. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2736. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2737. break;
  2738. case D3DFILL_WIREFRAME:
  2739. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2740. {
  2741. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2742. }
  2743. break;
  2744. case D3DFILL_SOLID:
  2745. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2746. break;
  2747. }
  2748. }
  2749. else
  2750. {
  2751. // TODO: Move into PrimProc.
  2752. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2753. {
  2754. case D3DFILL_POINT:
  2755. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2756. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2757. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2758. break;
  2759. case D3DFILL_WIREFRAME:
  2760. break;
  2761. case D3DFILL_SOLID:
  2762. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2763. break;
  2764. }
  2765. }
  2766. dwMask <<= 1;
  2767. }
  2768. pV0 = pV1;
  2769. pV1 = pVtx;
  2770. wFlags = 0;
  2771. if(dwEdgeFlags & dwMask)
  2772. wFlags |= D3DTRIFLAG_EDGEENABLE1;
  2773. dwMask <<= 1;
  2774. if(dwEdgeFlags & dwMask)
  2775. wFlags |= D3DTRIFLAG_EDGEENABLE2;
  2776. // TODO: Move into PrimProc.
  2777. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2778. {
  2779. case D3DFILL_POINT:
  2780. m_PrimProc.Point((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2781. m_PrimProc.Point((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2782. m_PrimProc.Point((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2783. break;
  2784. case D3DFILL_WIREFRAME:
  2785. if(NotCulled((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2))
  2786. {
  2787. if( wFlags& D3DTRIFLAG_EDGEENABLE1)
  2788. m_PrimProc.Line((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV0);
  2789. if( wFlags& D3DTRIFLAG_EDGEENABLE2)
  2790. m_PrimProc.Line((LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0);
  2791. if( wFlags& D3DTRIFLAG_EDGEENABLE3)
  2792. m_PrimProc.Line((LPD3DTLVERTEX)pV2, (LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV0);
  2793. }
  2794. break;
  2795. case D3DFILL_SOLID:
  2796. m_PrimProc.Tri((LPD3DTLVERTEX)pV0, (LPD3DTLVERTEX)pV1, (LPD3DTLVERTEX)pV2);
  2797. break;
  2798. }
  2799. }
  2800. void DoDrawOneGenEdgeFlagTriangleFan( UINT16 FvfStride, PUINT8 pVtx,
  2801. UINT cPrims, UINT32 dwEdgeFlags)
  2802. {
  2803. INT i;
  2804. RAST_GENERIC_VERTEX GV0, GV1, GV2;
  2805. PUINT8 pV0, pV1, pV2;
  2806. HRESULT hr;
  2807. pV2 = pVtx;
  2808. PackGenVertex( pV2, &GV2);
  2809. pVtx += FvfStride;
  2810. pV0 = pVtx;
  2811. PackGenVertex( pV0, &GV0);
  2812. pVtx += FvfStride;
  2813. pV1 = pVtx;
  2814. PackGenVertex( pV1, &GV1);
  2815. pVtx += FvfStride;
  2816. WORD wFlags = 0;
  2817. if(dwEdgeFlags & 0x2)
  2818. wFlags |= D3DTRIFLAG_EDGEENABLE1;
  2819. if(dwEdgeFlags & 0x1)
  2820. wFlags |= D3DTRIFLAG_EDGEENABLE3;
  2821. if(cPrims == 1) {
  2822. if(dwEdgeFlags & 0x4)
  2823. wFlags |= D3DTRIFLAG_EDGEENABLE2;
  2824. // TODO: Move into PrimProc.
  2825. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2826. {
  2827. case D3DFILL_POINT:
  2828. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2829. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2830. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2831. break;
  2832. case D3DFILL_WIREFRAME:
  2833. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2834. {
  2835. if( wFlags& D3DTRIFLAG_EDGEENABLE1)
  2836. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2837. if( wFlags& D3DTRIFLAG_EDGEENABLE2)
  2838. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2839. if( wFlags& D3DTRIFLAG_EDGEENABLE3)
  2840. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2841. }
  2842. break;
  2843. case D3DFILL_SOLID:
  2844. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2845. break;
  2846. }
  2847. return;
  2848. }
  2849. // TODO: Move into PrimProc.
  2850. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2851. {
  2852. case D3DFILL_POINT:
  2853. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2854. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2855. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2856. break;
  2857. case D3DFILL_WIREFRAME:
  2858. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2859. {
  2860. if( wFlags& D3DTRIFLAG_EDGEENABLE1)
  2861. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2862. if( wFlags& D3DTRIFLAG_EDGEENABLE2)
  2863. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2864. if( wFlags& D3DTRIFLAG_EDGEENABLE3)
  2865. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2866. }
  2867. break;
  2868. case D3DFILL_SOLID:
  2869. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2870. break;
  2871. }
  2872. UINT32 dwMask = 0x4;
  2873. for (i = (INT)cPrims - 2; i > 0; i--)
  2874. {
  2875. pV0 = pV1;
  2876. GV0 = GV1;
  2877. pV1 = pVtx;
  2878. PackGenVertex( pV1, &GV1);
  2879. pVtx += FvfStride;
  2880. if(true || (dwEdgeFlags & dwMask)!= 0)
  2881. {
  2882. // TODO: Move into PrimProc.
  2883. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2884. {
  2885. case D3DFILL_POINT:
  2886. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2887. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2888. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2889. break;
  2890. case D3DFILL_WIREFRAME:
  2891. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2892. {
  2893. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2894. }
  2895. break;
  2896. case D3DFILL_SOLID:
  2897. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2898. break;
  2899. }
  2900. }
  2901. else
  2902. {
  2903. // TODO: Move into PrimProc.
  2904. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2905. {
  2906. case D3DFILL_POINT:
  2907. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2908. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2909. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2910. break;
  2911. case D3DFILL_WIREFRAME:
  2912. break;
  2913. case D3DFILL_SOLID:
  2914. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2915. break;
  2916. }
  2917. }
  2918. dwMask <<= 1;
  2919. }
  2920. pV0 = pV1;
  2921. GV0 = GV1;
  2922. pV1 = pVtx;
  2923. PackGenVertex( pV1, &GV1);
  2924. wFlags = 0;
  2925. if(dwEdgeFlags & dwMask)
  2926. wFlags |= D3DTRIFLAG_EDGEENABLE1;
  2927. dwMask <<= 1;
  2928. if(dwEdgeFlags & dwMask)
  2929. wFlags |= D3DTRIFLAG_EDGEENABLE2;
  2930. // TODO: Move into PrimProc.
  2931. switch (m_RastCtx.pdwRenderState[D3DRS_FILLMODE])
  2932. {
  2933. case D3DFILL_POINT:
  2934. m_PrimProc.Point((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2935. m_PrimProc.Point((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2936. m_PrimProc.Point((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2937. break;
  2938. case D3DFILL_WIREFRAME:
  2939. if(NotCulled((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2))
  2940. {
  2941. if( wFlags& D3DTRIFLAG_EDGEENABLE1)
  2942. m_PrimProc.Line((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV0);
  2943. if( wFlags& D3DTRIFLAG_EDGEENABLE2)
  2944. m_PrimProc.Line((LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0);
  2945. if( wFlags& D3DTRIFLAG_EDGEENABLE3)
  2946. m_PrimProc.Line((LPD3DTLVERTEX)&GV2, (LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV0);
  2947. }
  2948. break;
  2949. case D3DFILL_SOLID:
  2950. m_PrimProc.Tri((LPD3DTLVERTEX)&GV0, (LPD3DTLVERTEX)&GV1, (LPD3DTLVERTEX)&GV2);
  2951. break;
  2952. }
  2953. }
  2954. };
  2955. }