fork download
  1. ////////////////////////////////////////////////////////////////////////
  2. // This font class was created by Azorbix (Matthew L) for Game-Deception
  3. // http://w...content-available-to-author-only...n.com http://f...content-available-to-author-only...n.com
  4. // irc://irc.rizon.net/game-deception
  5. //
  6. // A lot all of the CD3DFont::Initialize() code was created by Microsoft
  7. // (taken from the D3D9 SDK)
  8. //
  9. // Please note that this is NOT 100% complete yet, colour tags and
  10. // shadows are not implemented yet
  11. //
  12. // USAGE:
  13. // CD3DFont:
  14. // 1) Instanciate the class with the parameterized constructor
  15. // eg CD3DFont *g_pD3Dfont = new CD3DFont("Arial", 16, FCT_BOLD);
  16. //
  17. // 2) Call Initialize() after other rendering is ready
  18. // eg g_pD3DFont->Initialize(pD3Ddevice);
  19. //
  20. // 3) To begin rendering use Print function
  21. // eg g_pD3DFont->Print(10.0f, 50.0f, 0xFF00FF00, "Hello World", FT_BORDER);
  22. //
  23. // 4) call Invalidate() upon Reset of the D3D surface and re-initialize
  24. //
  25. // CD3DRender:
  26. // 1) Instanciate the class with the parameterized constructor
  27. // eg CD3DRender *g_pRender = new CD3DRender(128);
  28. //
  29. // 2) Call Initialize() after other rendering is ready
  30. // eg g_pRender->Initialize(pD3Ddevice);
  31. //
  32. // 3) To begin rendering, start rendering much like OpenGL
  33. // eg if( SUCCEEDED(g_pRender->Begin(D3DPT_TRIANGLELIST)) )
  34. // {
  35. // D3DAddQuad(g_pRender, 10.0f, 10.0f, 50.0f, 50.0f, 0xFFFF0000); //helper function
  36. // g_pRender->D3DColour(0xFF0000FF); //blue
  37. // g_pRender->D3DVertex2f(60.0f, 60.0f);
  38. // g_pRender->D3DVertex2f(60.0f, 110.0f);
  39. // g_pRender->D3DVertex2f(110.0f, 110.0f);
  40. // g_pRender->End();
  41. // }
  42. //
  43. // 4) call Invalidate() upon Reset of the D3D surface and re-initialize
  44. //
  45. // FASTER RENDERING (Advanced but NOT REQUIRED):
  46. // To enable faster rendering, it's ideal to call static function CD3DBaseRendering::BeginRender(); before
  47. // other font / primitive rendering code, and call CD3DBaseRendering::EndRender(); afterwards
  48. // *** IT IS CRUCIAL THAT YOU CALL EndRender FOR EVERY BeginRender() CALL ***
  49. // *** IMAGE RENDERING MAY BECOME CORRUPT IF YOU DO NOT ***
  50. // eg
  51. // if( SUCCEEDED(CD3DBaseRender::BeginRender()) )
  52. // {
  53. // //primitive and font rendering goes here
  54. // CD3DBaseRender::EndRender();
  55. // }
  56. //
  57. #include "main.h"
  58. #include "cd3dfont.h"
  59.  
  60. IDirect3DDevice9 *CD3DBaseRender:: m_pD3Ddev = NULL;
  61. IDirect3DStateBlock9 *CD3DBaseRender:: m_pD3DstateDraw = NULL;
  62. IDirect3DStateBlock9 *CD3DBaseRender:: m_pD3DstateNorm = NULL;
  63. int CD3DBaseRender:: m_renderCount = 0;
  64. int CD3DBaseRender:: m_numShared = 0;
  65. bool CD3DBaseRender:: m_statesOK = false;
  66.  
  67. inline d3dvertex_s Init2DVertex ( float x, float y, DWORD color, float tu, float tv )
  68. {
  69. d3dvertex_s v = { x, y, 1.0f, 1.0f, color, tu, tv };
  70. return v;
  71. }
  72.  
  73. CD3DBaseRender::CD3DBaseRender ()
  74. {
  75. m_numShared++;
  76. }
  77.  
  78. CD3DBaseRender::~CD3DBaseRender ()
  79. {
  80. if ( --m_numShared == 0 )
  81. DeleteStates();
  82. }
  83.  
  84. HRESULT CD3DBaseRender::Initialize ( IDirect3DDevice9 *pD3Ddev )
  85. {
  86. if ( m_pD3Ddev == NULL && (m_pD3Ddev = pD3Ddev) == NULL )
  87. return E_FAIL;
  88.  
  89. if ( !m_statesOK && FAILED(CreateStates()) )
  90. return E_FAIL;
  91.  
  92. return S_OK;
  93. }
  94.  
  95. HRESULT CD3DBaseRender::Invalidate ()
  96. {
  97. DeleteStates();
  98. return S_OK;
  99. }
  100.  
  101. HRESULT CD3DBaseRender::BeginRender ()
  102. {
  103. if ( !m_statesOK )
  104. return E_FAIL;
  105. if ( ++m_renderCount == 1 )
  106. {
  107. __try
  108. {
  109. m_pD3DstateNorm->Capture();
  110. }
  111. __except(EXCEPTION_EXECUTE_HANDLER)
  112. {
  113. --m_renderCount;
  114. return E_FAIL;
  115. }
  116. m_pD3DstateDraw->Apply();
  117. }
  118. return S_OK;
  119. }
  120.  
  121. HRESULT CD3DBaseRender::EndRender ()
  122. {
  123. if ( !m_statesOK )
  124. return E_FAIL;
  125.  
  126. m_renderCount--;
  127.  
  128. if ( m_renderCount == 0 )
  129. m_pD3DstateNorm->Apply();
  130. else if ( m_renderCount < 0 )
  131. m_renderCount = 0;
  132.  
  133. return S_OK;
  134. }
  135.  
  136. HRESULT CD3DBaseRender::CreateStates ()
  137. {
  138. for ( int iStateBlock = 0; iStateBlock < 2; iStateBlock++ )
  139. {
  140. m_pD3Ddev->BeginStateBlock();
  141. m_pD3Ddev->SetPixelShader( NULL );
  142. m_pD3Ddev->SetVertexShader( NULL );
  143.  
  144. m_pD3Ddev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  145. m_pD3Ddev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
  146. m_pD3Ddev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  147. m_pD3Ddev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
  148. m_pD3Ddev->SetRenderState( D3DRS_ALPHAREF, 0x08 );
  149. m_pD3Ddev->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
  150. m_pD3Ddev->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  151. m_pD3Ddev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
  152. m_pD3Ddev->SetRenderState( D3DRS_STENCILENABLE, FALSE );
  153. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, TRUE );
  154. m_pD3Ddev->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE );
  155. m_pD3Ddev->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_DISABLE );
  156. m_pD3Ddev->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
  157. m_pD3Ddev->SetRenderState( D3DRS_FOGENABLE, FALSE );
  158. m_pD3Ddev->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, FALSE );
  159. m_pD3Ddev->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN |
  160. D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA );
  161.  
  162. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  163. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  164. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  165. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  166. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  167. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  168. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
  169. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
  170. m_pD3Ddev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  171. m_pD3Ddev->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  172.  
  173. m_pD3Ddev->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
  174. m_pD3Ddev->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
  175. m_pD3Ddev->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
  176.  
  177. if ( iStateBlock )
  178. m_pD3Ddev->EndStateBlock( &m_pD3DstateDraw );
  179. else
  180. m_pD3Ddev->EndStateBlock( &m_pD3DstateNorm );
  181. }
  182.  
  183. m_statesOK = true;
  184.  
  185. return S_OK;
  186. }
  187.  
  188. HRESULT CD3DBaseRender::DeleteStates ()
  189. {
  190. SAFE_RELEASE( m_pD3DstateDraw );
  191. SAFE_RELEASE( m_pD3DstateNorm );
  192. m_statesOK = false;
  193.  
  194. return S_OK;
  195. }
  196.  
  197. CD3DFont::CD3DFont ( const char *szFontName, int fontHeight, DWORD dwCreateFlags )
  198. {
  199. strcpy( m_szFontName, (szFontName ? szFontName : "Arial") );
  200.  
  201. m_fontHeight = fontHeight;
  202. m_dwCreateFlags = dwCreateFlags;
  203.  
  204. m_isReady = false;
  205. m_statesOK = false;
  206.  
  207. m_pD3Dtex = NULL;
  208. m_pD3Dbuf = NULL;
  209. m_pRender = NULL;
  210.  
  211. m_maxTriangles = 224 * 2;
  212.  
  213. m_texWidth = m_texHeight = 0;
  214. m_chrSpacing = 0;
  215.  
  216. memset( m_fTexCoords, 0, sizeof(float) * 224 * 4 );
  217.  
  218. m_fChrHeight = 0.0;
  219. }
  220.  
  221. CD3DFont::~CD3DFont ()
  222. {
  223. Invalidate();
  224. }
  225.  
  226. /* god, what a mess */
  227. HRESULT CD3DFont::Initialize ( IDirect3DDevice9 *pD3Ddev )
  228. {
  229. if ( FAILED(CD3DBaseRender::Initialize(pD3Ddev)) )
  230. return E_FAIL;
  231.  
  232. if ( m_pRender == NULL && (m_pRender = new CD3DRender(16)) == NULL )
  233. return E_FAIL;
  234.  
  235. if ( FAILED(m_pRender->Initialize(pD3Ddev)) )
  236. return E_FAIL;
  237.  
  238. m_texWidth = m_texHeight = 512;
  239.  
  240. if ( FAILED(m_pD3Ddev->CreateTexture(m_texWidth, m_texHeight, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &m_pD3Dtex,
  241. NULL)) )
  242. return E_FAIL;
  243.  
  244. if ( FAILED(m_pD3Ddev->CreateVertexBuffer(m_maxTriangles * 3 * sizeof(d3dvertex_s),
  245. D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pD3Dbuf, NULL)) )
  246. {
  247. SAFE_RELEASE( m_pD3Dtex );
  248. return E_FAIL;
  249. }
  250.  
  251. DWORD *pBitmapBits;
  252. BITMAPINFO bmi;
  253.  
  254. memset( &bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER) );
  255. bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
  256. bmi.bmiHeader.biWidth = m_texWidth;
  257. bmi.bmiHeader.biHeight = -m_texHeight;
  258. bmi.bmiHeader.biPlanes = 1;
  259. bmi.bmiHeader.biCompression = BI_RGB;
  260. bmi.bmiHeader.biBitCount = 32;
  261.  
  262. HDC hDC = CreateCompatibleDC( NULL );
  263. HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (void **) &pBitmapBits, NULL, 0 );
  264. SetMapMode( hDC, MM_TEXT );
  265.  
  266. int iHeight = -m_fontHeight * (int)GetDeviceCaps( hDC, LOGPIXELSY ) / 72;
  267.  
  268. HFONT hFont = CreateFont( iHeight, 0, 0, 0, (m_dwCreateFlags & FCR_BOLD) ? FW_BOLD : FW_NORMAL,
  269. m_dwCreateFlags & FCR_ITALICS, false, false, DEFAULT_CHARSET, OUT_TT_PRECIS,
  270. CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, m_szFontName );
  271.  
  272. if ( hFont == NULL )
  273. {
  274. DeleteObject( hbmBitmap );
  275. DeleteDC( hDC );
  276. DeleteObject( hFont );
  277. SAFE_RELEASE( m_pD3Dtex );
  278. return E_FAIL;
  279. }
  280.  
  281. SelectObject( hDC, hbmBitmap );
  282. SelectObject( hDC, hFont );
  283.  
  284. RECT all = { 0, 0, m_texWidth - 1, m_texWidth - 1 };
  285. HBRUSH green = CreateSolidBrush( RGB(0, 255, 0) );
  286. FillRect( hDC, &all, green );
  287. DeleteObject( green );
  288.  
  289. SetBkMode( hDC, TRANSPARENT );
  290. SetTextAlign( hDC, TA_TOP );
  291.  
  292. SIZE size;
  293. char ch = ' ';
  294.  
  295. GetTextExtentPoint32( hDC, &ch, 1, &size );
  296.  
  297. m_chrSpacing = ( size.cx + 3 ) / 4;
  298. m_fChrHeight = (float)( size.cy );
  299.  
  300. if ( m_dwCreateFlags & FCR_BORDER )
  301. {
  302. size.cx += 2;
  303. size.cy += 2;
  304. }
  305.  
  306. int y = 0, x = ( size.cx + 3 ) / 4;
  307.  
  308. for ( int c = 32; c < 256; c++ )
  309. {
  310. ch = (char)c;
  311.  
  312. GetTextExtentPoint32( hDC, &ch, 1, &size );
  313. if ( m_dwCreateFlags & FCR_BORDER )
  314. {
  315. size.cx += 3;
  316. size.cy += 3;
  317. }
  318.  
  319. if ( x + size.cx + m_chrSpacing > m_texWidth )
  320. {
  321. x = m_chrSpacing;
  322. if ( y + size.cy * 2 + 2 < m_texHeight )
  323. y += size.cy + 1;
  324. }
  325.  
  326. RECT rect = { x, y, x + size.cx, y + size.cy };
  327.  
  328. if ( m_dwCreateFlags & FCR_BORDER )
  329. {
  330. // XXX retarded :p use font outline instead
  331. SetTextColor( hDC, RGB(0, 0, 0) );
  332. x++;
  333. y++;
  334. ExtTextOut( hDC, x - 1, y - 1, ETO_CLIPPED, &rect, &ch, 1, NULL );
  335. ExtTextOut( hDC, x, y - 1, ETO_CLIPPED, &rect, &ch, 1, NULL );
  336. ExtTextOut( hDC, x + 1, y - 1, ETO_CLIPPED, &rect, &ch, 1, NULL );
  337. ExtTextOut( hDC, x + 1, y, ETO_CLIPPED, &rect, &ch, 1, NULL );
  338. ExtTextOut( hDC, x + 1, y + 1, ETO_CLIPPED, &rect, &ch, 1, NULL );
  339. ExtTextOut( hDC, x, y + 1, ETO_CLIPPED, &rect, &ch, 1, NULL );
  340. ExtTextOut( hDC, x - 1, y + 1, ETO_CLIPPED, &rect, &ch, 1, NULL );
  341. ExtTextOut( hDC, x - 1, y, ETO_CLIPPED, &rect, &ch, 1, NULL );
  342. SetTextColor( hDC, RGB(255, 0, 0) );
  343. ExtTextOut( hDC, x, y, ETO_CLIPPED, &rect, &ch, 1, NULL );
  344. x--;
  345. y--;
  346. }
  347. else
  348. {
  349. SetTextColor( hDC, RGB(255, 0, 0) );
  350. ExtTextOut( hDC, x, y, ETO_CLIPPED, &rect, &ch, 1, NULL );
  351. }
  352.  
  353. //tu src + dst
  354. m_fTexCoords[c - 32][0] = (float)( x + 0 - m_chrSpacing ) / (float)m_texWidth;
  355. m_fTexCoords[c - 32][2] = (float)( x + size.cx + m_chrSpacing ) / (float)m_texWidth;
  356.  
  357. //tv src + dst
  358. m_fTexCoords[c - 32][1] = (float)( y + 0 + 0 ) / (float)m_texHeight;
  359. m_fTexCoords[c - 32][3] = (float)( y + size.cy + 0 ) / (float)m_texHeight;
  360.  
  361. x += size.cx + ( 2 * m_chrSpacing );
  362. }
  363.  
  364. D3DLOCKED_RECT d3dlr;
  365. m_pD3Dtex->LockRect( 0, &d3dlr, 0, 0 );
  366.  
  367. BYTE *pDstRow = (BYTE *)d3dlr.pBits;
  368. WORD *pDst16;
  369.  
  370. for ( y = 0; y < m_texHeight; y++ )
  371. {
  372. pDst16 = (WORD *)pDstRow;
  373.  
  374. for ( x = 0; x < m_texWidth; x++ )
  375. {
  376. DWORD pixel = pBitmapBits[m_texWidth * y + x];
  377. BYTE bAlpha = 15 - ( ((BYTE) (pixel >> 8)) >> 4 ); // green channel
  378. BYTE bValue = ( (BYTE) (pixel >> 16) ) >> 4; // red channel
  379. *pDst16 = ( WORD ) ( bAlpha << 12 ) | ( bValue << 8 ) | ( bValue << 4 ) | ( bValue );
  380. pDst16++;
  381. }
  382.  
  383. pDstRow += d3dlr.Pitch;
  384. }
  385.  
  386. m_pD3Dtex->UnlockRect( 0 );
  387.  
  388. DeleteObject( hbmBitmap );
  389. DeleteDC( hDC );
  390. DeleteObject( hFont );
  391.  
  392. m_isReady = true;
  393.  
  394. return S_OK;
  395. }
  396.  
  397. HRESULT CD3DFont::Invalidate ()
  398. {
  399. m_isReady = false;
  400.  
  401. SAFE_RELEASE( m_pD3Dtex );
  402. SAFE_RELEASE( m_pD3Dbuf );
  403.  
  404. //SAFE_RELEASE(m_pD3DstateDraw);
  405. //SAFE_RELEASE(m_pD3DstateNorm);
  406. m_pRender->Invalidate();
  407.  
  408. CD3DBaseRender::Invalidate();
  409. return S_OK;
  410. }
  411.  
  412. HRESULT CD3DFont::Print ( float x, float y, DWORD color, const char *szText, bool textcoloring )
  413. {
  414. if ( !m_isReady )
  415. return E_FAIL;
  416.  
  417. float strWidth = DrawLength( szText );
  418.  
  419. x -= (float)m_chrSpacing;
  420.  
  421. if ( FAILED(this->BeginRender()) )
  422. return E_FAIL;
  423.  
  424. //
  425. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  426. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  427.  
  428. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, false );
  429. m_pD3Ddev->SetRenderState ( D3DRS_ZENABLE, false );
  430.  
  431. //
  432.  
  433. DWORD fvf;
  434. m_pD3Ddev->GetFVF( &fvf );
  435. m_pD3Ddev->SetFVF( D3DFVF_BITMAPFONT );
  436. m_pD3Ddev->SetTexture( 0, m_pD3Dtex );
  437. m_pD3Ddev->SetStreamSource( 0, m_pD3Dbuf, 0, sizeof(d3dvertex_s) );
  438.  
  439. DWORD currentcolor = color;
  440. bool GettingColor = false;
  441.  
  442. while ( *szText )
  443. {
  444. UINT usedTriangles = 0;
  445. d3dvertex_s *pVertex;
  446.  
  447. if ( FAILED(m_pD3Dbuf->Lock(0, 0, (void **) &pVertex, D3DLOCK_DISCARD)) )
  448. {
  449. m_pD3Ddev->SetFVF( fvf );
  450. this->EndRender();
  451. return E_FAIL;
  452. }
  453.  
  454.  
  455. for ( ; *szText; szText++ )
  456. {
  457. if(textcoloring)
  458. {
  459. if(*szText == '{')
  460. {
  461. char ccolor[9] = {0};
  462. unsigned long tempcolor = 0;
  463. for(unsigned int i = 1; i < 10; ++i)
  464. {
  465. if(*(szText+i))
  466. {
  467. if(i == 9)
  468. {
  469. if(*(szText+(i)) != '}')
  470. {
  471. break;
  472. }
  473. if(sscanf(ccolor, "%x", &tempcolor) != 1)
  474. {
  475. break;
  476. }
  477. currentcolor = tempcolor;
  478. szText+=9;
  479. GettingColor = true;
  480. break;
  481. }
  482. ccolor[i-1] = *(szText+i);
  483. }
  484. else
  485. {
  486. break;
  487. }
  488. }
  489. }
  490. }
  491. if(GettingColor)
  492. {
  493. GettingColor = false;
  494. continue;
  495. }
  496. int c = *(unsigned char *)szText - 32;
  497. if ( !(c >= 0 && c < 224) )
  498. continue;
  499.  
  500. float tx1 = m_fTexCoords[c][0];
  501. float tx2 = m_fTexCoords[c][2];
  502. float ty1 = m_fTexCoords[c][1];
  503. float ty2 = m_fTexCoords[c][3];
  504. float w = ( tx2 - tx1 ) * m_texWidth;
  505. float h = ( ty2 - ty1 ) * m_texHeight;
  506.  
  507. *pVertex++ = Init2DVertex( x - 0.5f, y - 0.5f, currentcolor, tx1, ty1 ); //topleft
  508. *pVertex++ = Init2DVertex( x + w - 0.5f, y - 0.5f, currentcolor, tx2, ty1 ); //topright
  509. *pVertex++ = Init2DVertex( x - 0.5f, y + h - 0.5f, currentcolor, tx1, ty2 ); //bottomleft
  510. *pVertex++ = Init2DVertex( x + w - 0.5f, y - 0.5f, currentcolor, tx2, ty1 ); //topright
  511. *pVertex++ = Init2DVertex( x + w - 0.5f, y + h - 0.5f, currentcolor, tx2, ty2 ); //bottomright
  512. *pVertex++ = Init2DVertex( x - 0.5f, y + h - 0.5f, currentcolor, tx1, ty2 ); //bottomleft
  513. if ( m_dwCreateFlags & FCR_BORDER )
  514. w -= 2.0f;
  515.  
  516. x += w - ( m_chrSpacing * 2 );
  517.  
  518. usedTriangles += 2;
  519. if ( usedTriangles >= m_maxTriangles )
  520. break;
  521. }
  522.  
  523. if ( usedTriangles > 0 )
  524. {
  525. m_pD3Dbuf->Unlock();
  526. m_pD3Ddev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, usedTriangles );
  527. }
  528. }
  529.  
  530. m_pD3Ddev->SetFVF( fvf );
  531.  
  532. //
  533. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  534. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  535. m_pD3Ddev->SetRenderState ( D3DRS_ZENABLE, true );
  536. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, true );
  537. //
  538. this->EndRender();
  539.  
  540. return S_OK;
  541. }
  542.  
  543. HRESULT CD3DFont::PrintShadow ( float x, float y, DWORD color, const char *szText )
  544. {
  545. Print( x, y, color, szText );
  546.  
  547. return S_OK;
  548. }
  549.  
  550. float CD3DFont::DrawLength ( const char *szText ) const
  551. {
  552. float len = 0.0f;
  553. float sub = ( m_dwCreateFlags & FCR_BORDER ) ? 2.0f : 0.0f;
  554.  
  555. for ( const char *p = szText; *p; p++ )
  556. {
  557. int c = *(unsigned char *)p - 32;
  558. if ( c >= 0 && c < 224 )
  559. len += ( (m_fTexCoords[c][2] - m_fTexCoords[c][0]) * m_texWidth - sub ) - m_chrSpacing * 2;
  560. }
  561.  
  562. return len;
  563. }
  564.  
  565. CD3DRender::CD3DRender ( int numVertices )
  566. {
  567. m_canRender = false;
  568.  
  569. m_pD3Dbuf = NULL;
  570. m_pVertex = NULL;
  571.  
  572. m_color = 0;
  573. m_tu = 0.0f;
  574. m_tv = 0.0f;
  575. m_texture = NULL;
  576.  
  577. m_maxVertex = numVertices;
  578. m_curVertex = 0;
  579. }
  580.  
  581. CD3DRender::~CD3DRender ()
  582. {
  583. Invalidate();
  584. }
  585.  
  586. HRESULT CD3DRender::Initialize ( IDirect3DDevice9 *pD3Ddev )
  587. {
  588. if ( !m_canRender )
  589. {
  590. if ( FAILED(CD3DBaseRender::Initialize(pD3Ddev)) )
  591. return E_FAIL;
  592. if ( FAILED(m_pD3Ddev->CreateVertexBuffer(m_maxVertex * sizeof(d3dvertex_s),
  593. D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pD3Dbuf, NULL)) )
  594. return E_FAIL;
  595.  
  596. m_canRender = true;
  597. }
  598.  
  599. return S_OK;
  600. }
  601.  
  602. HRESULT CD3DRender::Invalidate ()
  603. {
  604. SAFE_RELEASE( m_pD3Dbuf );
  605. SAFE_RELEASE( m_texture );
  606. //m_pVertex = NULL;
  607.  
  608. //SAFE_RELEASE(m_pD3DstateDraw);
  609. //SAFE_RELEASE(m_pD3DstateNorm);
  610. //CD3DBaseRender::Invalidate();
  611. //m_canRender = false;
  612.  
  613. return S_OK;
  614. }
  615.  
  616. HRESULT CD3DRender::Begin ( D3DPRIMITIVETYPE primType )
  617. {
  618. if ( !m_canRender )
  619. return E_FAIL;
  620.  
  621. if ( m_pVertex != NULL )
  622. return E_FAIL;
  623.  
  624. if ( FAILED(m_pD3Dbuf->Lock(0, 0, (void **) &m_pVertex, D3DLOCK_DISCARD)) )
  625. return E_FAIL;
  626.  
  627. m_primType = primType;
  628.  
  629. return S_OK;
  630. }
  631.  
  632. HRESULT CD3DRender::End ()
  633. {
  634. int numPrims;
  635.  
  636. m_pVertex = NULL;
  637.  
  638. if ( !m_canRender )
  639. {
  640. m_curVertex = 0;
  641. return E_FAIL;
  642. }
  643.  
  644. if ( FAILED(CD3DBaseRender::BeginRender()) )
  645. return E_FAIL;
  646.  
  647. switch ( m_primType )
  648. {
  649. case D3DPT_POINTLIST:
  650. numPrims = m_curVertex;
  651. break;
  652.  
  653. case D3DPT_LINELIST:
  654. numPrims = m_curVertex / 2;
  655. break;
  656.  
  657. case D3DPT_LINESTRIP:
  658. numPrims = m_curVertex - 1;
  659. break;
  660.  
  661. case D3DPT_TRIANGLELIST:
  662. numPrims = m_curVertex / 3;
  663. break;
  664.  
  665. case D3DPT_TRIANGLESTRIP:
  666. case D3DPT_TRIANGLEFAN:
  667. numPrims = m_curVertex - 2;
  668. break;
  669.  
  670. default:
  671. numPrims = 0;
  672. break;
  673. }
  674.  
  675. m_curVertex = 0;
  676.  
  677. if ( numPrims > 0 )
  678. {
  679. m_pD3Dbuf->Unlock();
  680.  
  681. DWORD fvf;
  682. m_pD3Ddev->GetFVF( &fvf );
  683.  
  684. if ( m_texture == NULL )
  685. {
  686. m_pD3Ddev->SetFVF( D3DFVF_PRIMITIVES );
  687. m_pD3Ddev->SetTexture( 0, NULL );
  688. }
  689. else
  690. {
  691. m_pD3Ddev->SetFVF( D3DFVF_BITMAPFONT );
  692. m_pD3Ddev->SetTexture( 0, m_texture );
  693. }
  694.  
  695. m_pD3Ddev->SetStreamSource( 0, m_pD3Dbuf, 0, sizeof(d3dvertex_s) );
  696.  
  697. m_pD3Ddev->DrawPrimitive( m_primType, 0, numPrims );
  698.  
  699. m_pD3Ddev->SetFVF( fvf );
  700. }
  701.  
  702. CD3DBaseRender::EndRender();
  703.  
  704. return S_OK;
  705. }
  706.  
  707. HRESULT CD3DRender::D3DColor ( DWORD color )
  708. {
  709. m_color = color;
  710. return m_canRender ? S_OK : E_FAIL;
  711. return S_OK;
  712. }
  713.  
  714. void CD3DRender::D3DBindTexture ( IDirect3DTexture9 *texture )
  715. {
  716. m_texture = texture;
  717. }
  718.  
  719. void CD3DRender::D3DTexCoord2f ( float u, float v )
  720. {
  721. m_tu = u;
  722. m_tv = v;
  723. }
  724.  
  725. HRESULT CD3DRender::D3DVertex2f ( float x, float y )
  726. {
  727. if ( m_canRender && m_pVertex && ++m_curVertex < m_maxVertex )
  728. *m_pVertex++ = Init2DVertex( x, y, m_color, m_tu, m_tv );
  729. else
  730. return E_FAIL;
  731.  
  732. return S_OK;
  733. }
  734.  
  735. void CD3DRender::D3DTexQuad ( float sx, float sy, float ex, float ey, float su, float sv, float eu, float ev )
  736. {
  737. if ( SUCCEEDED(Begin(D3DPT_TRIANGLELIST)) )
  738. {
  739. D3DColor( D3DCOLOR_XRGB(255, 255, 255) );
  740. D3DTexCoord2f( su, sv );
  741. D3DVertex2f( sx, sy );
  742. D3DTexCoord2f( eu, sv );
  743. D3DVertex2f( ex, sy );
  744. D3DTexCoord2f( su, ev );
  745. D3DVertex2f( sx, ey );
  746.  
  747. D3DTexCoord2f( su, ev );
  748. D3DVertex2f( sx, ey );
  749. D3DTexCoord2f( eu, sv );
  750. D3DVertex2f( ex, sy );
  751. D3DTexCoord2f( eu, ev );
  752. D3DVertex2f( ex, ey );
  753. End();
  754. }
  755. }
  756.  
  757. void CD3DRender::D3DBox ( float x, float y, float w, float h, D3DCOLOR color )
  758. {
  759. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  760. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  761. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, false );
  762. m_pD3Ddev->SetRenderState ( D3DRS_ZENABLE, false );
  763. if ( SUCCEEDED(Begin(D3DPT_TRIANGLELIST)) )
  764. {
  765. D3DColor( color );
  766. D3DVertex2f( x, y );
  767. D3DVertex2f( x + w, y );
  768. D3DVertex2f( x, y + h );
  769. D3DVertex2f( x, y + h );
  770. D3DVertex2f( x + w, y );
  771. D3DVertex2f( x + w, y + h );
  772. End();
  773. }
  774. // reset states
  775. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  776. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  777. m_pD3Ddev->SetRenderState ( D3DRS_ZENABLE, true );
  778. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, true );
  779. }
  780.  
  781. void CD3DRender::D3DBoxi ( int x, int y, int w, int h, D3DCOLOR color, int maxW )
  782. {
  783. if ( maxW )
  784. {
  785. if ( w >= maxW )
  786. ( w = maxW );
  787. D3DBox( (float)x, (float)y, (float)w, (float)h, color );
  788. }
  789. else
  790. {
  791. D3DBox( (float)x, (float)y, (float)w, (float)h, color );
  792. }
  793. }
  794.  
  795. void CD3DRender::D3DBoxBorder ( float x, float y, float w, float h, D3DCOLOR border_color, D3DCOLOR color )
  796. {
  797. D3DBox( x, y, w, 1.0f, border_color );
  798. D3DBox( x + w, y, 1.0f, h, border_color );
  799. D3DBox( x, y, 1.0f, h, border_color );
  800. D3DBox( x, y + h, w, 1.0f, border_color );
  801. D3DBox( x + 1.0f, y + 1.0f, w - 1.0f, h - 1.0f, color );
  802. }
  803.  
  804. void CD3DRender::D3DBoxBorderi ( int x, int y, int w, int h, D3DCOLOR border_color, D3DCOLOR color )
  805. {
  806. D3DBoxBorder( (float)x, (float)y, (float)w, (float)h, border_color, color );
  807. }
  808.  
  809. bool CD3DRender::DrawLine ( const D3DXVECTOR3 &a, const D3DXVECTOR3 &b, DWORD dwColor )
  810. {
  811. if ( FAILED(CD3DBaseRender::BeginRender()) )
  812. return false;
  813.  
  814. ////////////////////////////////////////////////////
  815. // Make sure we have a valid vertex buffer.
  816. if ( m_pD3Dbuf == NULL )
  817. {
  818. return false;
  819. }
  820.  
  821. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  822. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  823. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  824. //m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  825.  
  826. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, false );
  827. m_pD3Ddev->SetRenderState ( D3DRS_ZENABLE, false );
  828. //m_pD3Ddev->SetRenderState ( D3DRS_LIGHTING, false );
  829. D3DLVERTEX lineList[2];
  830.  
  831. //////////////////////////////////////////////////
  832. // Lock the vertex buffer and copy in the verts.
  833. m_pD3Dbuf->Lock( 0, 0, (void **) &lineList, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK ); // flogs: D3DLOCK_NOSYSLOCK, D3DLOCK_DISCARD
  834. {
  835. lineList[0].x = a.x;
  836. lineList[0].y = a.y;
  837. lineList[0].z = a.z;
  838. lineList[0].color = dwColor;
  839. lineList[0].specular = dwColor;
  840.  
  841. lineList[1].x = b.x;
  842. lineList[1].y = b.y;
  843. lineList[1].z = b.z;
  844. lineList[1].color = dwColor;
  845. lineList[1].specular = dwColor;
  846. }
  847.  
  848. m_pD3Dbuf->Unlock();
  849.  
  850. // store FVF to restore original at the end of this function
  851. DWORD fvf;
  852. m_pD3Ddev->GetFVF( &fvf );
  853. m_pD3Ddev->SetFVF( D3DFVF_LVERTEX );
  854. //m_pD3Ddev->SetFVF( D3DFVF_PRIMITIVES );
  855.  
  856. ////////////////////////////////////////////////////
  857. // Draw!
  858. m_pD3Ddev->DrawPrimitiveUP( D3DPT_LINESTRIP, 1, lineList, sizeof(lineList) / 2 );
  859.  
  860. // reset states
  861. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  862. m_pD3Ddev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  863. m_pD3Ddev->SetRenderState ( D3DRS_ZENABLE, true );
  864. m_pD3Ddev->SetRenderState( D3DRS_CLIPPING, true );
  865.  
  866. // restore FVF
  867. m_pD3Ddev->SetFVF( fvf );
  868.  
  869. CD3DBaseRender::EndRender();
  870.  
  871. return true;
  872. }
  873.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty