00001
00002
00003
00004
00005
00006
00007
00008 #ifndef STRICT
00009 #define STRICT
00010 #endif
00011
00012 #include "dxgsg8base.h"
00013 #include <stdio.h>
00014 #include <tchar.h>
00015 #include <d3dx8.h>
00016 #include "d3dfont8.h"
00017
00018
00019
00020
00021
00022 struct FONT2DVERTEX {
00023 D3DXVECTOR4 p; DWORD color; FLOAT tu, tv;
00024 };
00025 struct FONT3DVERTEX {
00026 D3DXVECTOR3 p; D3DXVECTOR3 n; FLOAT tu, tv;
00027 };
00028
00029 inline FONT2DVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,
00030 FLOAT tu, FLOAT tv ) {
00031 FONT2DVERTEX v; v.p = p; v.color = color; v.tu = tu; v.tv = tv;
00032 return v;
00033 }
00034
00035 inline FONT3DVERTEX InitFont3DVertex( const D3DXVECTOR3& p, const D3DXVECTOR3& n,
00036 FLOAT tu, FLOAT tv ) {
00037 FONT3DVERTEX v; v.p = p; v.n = n; v.tu = tu; v.tv = tv;
00038 return v;
00039 }
00040
00041
00042
00043
00044
00045 CD3DFont::CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags ) {
00046 _tcscpy( m_strFontName, strFontName );
00047 m_dwFontHeight = dwHeight;
00048 m_dwFontFlags = dwFlags;
00049
00050 m_pd3dDevice = NULL;
00051 m_pTexture = NULL;
00052 m_pVB = NULL;
00053
00054 m_dwSavedStateBlock = NULL;
00055 m_dwDrawTextStateBlock = NULL;
00056
00057 ClearBeginEndData ( ) ;
00058 m_bBeginText = false ;
00059 }
00060
00061
00062
00063
00064
00065 CD3DFont::~CD3DFont() {
00066 DeleteDeviceObjects();
00067 }
00068
00069
00070
00071
00072
00073
00074 HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
00075 HRESULT hr;
00076
00077
00078 m_pd3dDevice = pd3dDevice;
00079
00080
00081 m_fTextScale = 1.0f;
00082
00083
00084
00085 if(m_dwFontHeight > 40)
00086 m_dwTexWidth = m_dwTexHeight = 2048;
00087 else if(m_dwFontHeight > 32)
00088 m_dwTexWidth = m_dwTexHeight = 1024;
00089 else if(m_dwFontHeight > 16)
00090 m_dwTexWidth = m_dwTexHeight = 512;
00091 else
00092 m_dwTexWidth = m_dwTexHeight = 256;
00093
00094
00095 DWORD* pBitmapBits;
00096 BITMAPINFO bmi;
00097 ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
00098 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00099 bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
00100 bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
00101 bmi.bmiHeader.biPlanes = 1;
00102 bmi.bmiHeader.biCompression = BI_RGB;
00103 bmi.bmiHeader.biBitCount = 32;
00104
00105
00106 HDC hDC = CreateCompatibleDC( NULL );
00107 HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
00108 (VOID**)&pBitmapBits, NULL, 0 );
00109 SetMapMode( hDC, MM_TEXT );
00110
00111
00112
00113 INT nHeight = -MulDiv( m_dwFontHeight,
00114 (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
00115 DWORD dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
00116 DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE;
00117 HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold,
00118
00119 FALSE ,
00120
00121
00122 FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
00123 CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
00124 VARIABLE_PITCH, m_strFontName );
00125 if(NULL==hFont) {
00126 dxgsg8_cat.error() << "CD3DFont InitDeviceObjects(): initial CreateFont failed! GetLastError=" << GetLastError() << endl;
00127 return E_FAIL;
00128 }
00129
00130 HBITMAP hbmOld = ( HBITMAP ) SelectObject ( hDC, hbmBitmap );
00131 HFONT hfOld = ( HFONT ) SelectObject ( hDC, hFont );
00132
00133
00134 SetTextColor( hDC, RGB(255,255,255) );
00135 SetBkColor( hDC, 0x00000000 );
00136 SetTextAlign( hDC, TA_TOP );
00137
00138
00139
00140 DWORD x = 0;
00141 DWORD y = 0;
00142 TCHAR str[2] = _T("x");
00143 SIZE size;
00144 SIZE sizes [ 127 - 32 ] ;
00145
00146 for(TCHAR c=32; c<127; c++) {
00147 str[0] = c;
00148
00149
00150
00151
00152
00153 GetTextExtentPoint32 ( hDC, str, 1, & sizes [ c - 32 ] );
00154 } ;
00155
00156 static DWORD TexturesSizes [ 5 ] = { 128 , 256 , 512 , 1024 , 2048} ;
00157 DWORD dwTexSize = 0 ;
00158 for(DWORD iTex = 0 ; iTex < 5 ; ++ iTex) {
00159
00160 x = 0 ;
00161 y = 0 ;
00162 for(TCHAR c=32; c<127; c++) {
00163 if((DWORD)( x + sizes[ c - 32 ].cx+1) > TexturesSizes [ iTex ]) {
00164 x = 0;
00165 y += sizes[ c - 32 ].cy+1;
00166
00167 if((DWORD) ( y + sizes[ 0 ].cy + 1 ) >= TexturesSizes [ iTex ]) {
00168
00169 break ;
00170 };
00171 };
00172 x += sizes[ c - 32 ].cx + 2 ;
00173 } ;
00174
00175 if((DWORD) ( y + sizes[ 0 ].cy + 1 ) < TexturesSizes [ iTex ]) {
00176
00177 dwTexSize = TexturesSizes [ iTex ] ;
00178 break ;
00179 };
00180 } ;
00181
00182 m_dwTexWidth = m_dwTexHeight = dwTexSize ;
00183
00184
00185
00186
00187 SelectObject ( hDC, hbmOld );
00188 SelectObject ( hDC, hfOld );
00189
00190
00191 DeleteObject( hbmBitmap );
00192 DeleteObject( hFont );
00193 DeleteDC( hDC );
00194
00195
00196 if(dwTexSize == 0) {
00197 dxgsg8_cat.error() << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n";
00198 return E_FAIL;
00199 }
00200
00201
00202
00203
00204 ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
00205 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00206 bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
00207 bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
00208 bmi.bmiHeader.biPlanes = 1;
00209 bmi.bmiHeader.biCompression = BI_RGB;
00210 bmi.bmiHeader.biBitCount = 32;
00211
00212
00213 hDC = CreateCompatibleDC( NULL );
00214 hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
00215 (VOID**)&pBitmapBits, NULL, 0 );
00216 SetMapMode( hDC, MM_TEXT );
00217
00218
00219
00220 nHeight = -MulDiv( m_dwFontHeight,
00221 (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
00222 dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
00223 dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE;
00224 hFont = CreateFont( nHeight, 0, 0, 0, dwBold,
00225 FALSE ,
00226 FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
00227 CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
00228 VARIABLE_PITCH, m_strFontName );
00229
00230 if(NULL==hFont) {
00231 dxgsg8_cat.error() << "CD3DFont InitDeviceObjects(): optimal CreateFont failed! GetLastError=" << GetLastError() << endl;
00232 return E_FAIL;
00233 }
00234
00235 hbmOld = ( HBITMAP ) SelectObject ( hDC, hbmBitmap );
00236 hfOld = ( HFONT ) SelectObject ( hDC, hFont );
00237
00238
00239 SetTextColor( hDC, RGB(255,255,255) );
00240 SetBkColor( hDC, 0x00000000 );
00241 SetTextAlign( hDC, TA_TOP );
00242
00243
00244
00245 D3DCAPS8 d3dCaps;
00246 m_pd3dDevice->GetDeviceCaps( &d3dCaps );
00247
00248 if(m_dwTexWidth > d3dCaps.MaxTextureWidth) {
00249 m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwTexWidth;
00250 m_dwTexWidth = m_dwTexHeight = d3dCaps.MaxTextureWidth;
00251 };
00252
00253
00254 hr = m_pd3dDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
00255 0, D3DFMT_A4R4G4B4,
00256 D3DPOOL_MANAGED, &m_pTexture );
00257
00258 if(FAILED(hr)) {
00259 SelectObject ( hDC, hbmOld );
00260 SelectObject ( hDC, hfOld );
00261
00262 DeleteObject( hbmBitmap );
00263 DeleteObject( hFont );
00264 DeleteDC( hDC );
00265
00266 dxgsg8_cat.error() << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr);
00267 return hr;
00268 };
00269
00270
00271
00272 x = 0 ;
00273 y = 0 ;
00274
00275 for(TCHAR c=32; c<127; c++) {
00276 str[0] = c;
00277 GetTextExtentPoint32( hDC, str, 1, &size );
00278 if((DWORD)(x+size.cx+1) > m_dwTexWidth) {
00279 x = 0;
00280 y += size.cy+1;
00281 }
00282
00283
00284
00285
00286 ExtTextOut( hDC, x + 1, y, ETO_OPAQUE, NULL, str, 1, NULL );
00287
00288 m_fTexCoords[c-32][0] = ( (FLOAT) x + 0.5f ) / m_dwTexWidth ;
00289 m_fTexCoords[c-32][1] = ( (FLOAT) y + 0.5f ) / m_dwTexHeight ;
00290 m_fTexCoords[c-32][2] = ( (FLOAT) x + 0.5f + size.cx ) / m_dwTexWidth;
00291 m_fTexCoords[c-32][3] = ( (FLOAT) y + 0.5f + size.cy ) / m_dwTexHeight;
00292
00293
00294 x += size.cx + 2 ;
00295 }
00296
00297
00298 D3DLOCKED_RECT d3dlr;
00299 m_pTexture->LockRect( 0, &d3dlr, 0, 0 );
00300 BYTE* pDstRow = (BYTE*)d3dlr.pBits;
00301 WORD* pDst16;
00302 BYTE bAlpha;
00303
00304 for(y=0; y < m_dwTexHeight; y++) {
00305 pDst16 = (WORD*)pDstRow;
00306 for(x=0; x < m_dwTexWidth; x++) {
00307 bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
00308 if(bAlpha > 0) {
00309 *pDst16++ = (bAlpha << 12) | 0x0fff;
00310 } else {
00311 *pDst16++ = 0x0000;
00312 }
00313 }
00314 pDstRow += d3dlr.Pitch;
00315 }
00316
00317
00318 m_pTexture->UnlockRect(0);
00319
00320 SelectObject ( hDC, hbmOld );
00321 SelectObject ( hDC, hfOld );
00322
00323 DeleteObject( hbmBitmap );
00324 DeleteObject( hFont );
00325 DeleteDC( hDC );
00326
00327 return RestoreDeviceObjects();
00328 }
00329
00330
00331
00332
00333
00334 HRESULT CD3DFont::RestoreDeviceObjects() {
00335 HRESULT hr;
00336
00337
00338 if(FAILED( hr = m_pd3dDevice->CreateVertexBuffer(
00339
00340 MAX_NUM_VERTICES*sizeof(FONT3DVERTEX ),
00341 D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
00342 D3DPOOL_DEFAULT,
00343 &m_pVB ) )) {
00344 dxgsg8_cat.error() << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr);
00345 return hr;
00346 }
00347
00348 PRINT_REFCNT(dxgsg8,m_pd3dDevice);
00349
00350
00351 for(UINT which=0; which<2; which++) {
00352 m_pd3dDevice->BeginStateBlock();
00353 m_pd3dDevice->SetTexture( 0, m_pTexture );
00354
00355 if(D3DFONT_ZENABLE & m_dwFontFlags)
00356 m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
00357 else
00358 m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
00359
00360 m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
00361 m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
00362 m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
00363 m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
00364 m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
00365 m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
00366 m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
00367 m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
00368 m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
00369 m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
00370 m_pd3dDevice->SetRenderState( D3DRS_EDGEANTIALIAS, FALSE );
00371 m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE );
00372 m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, FALSE );
00373 m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
00374 m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
00375 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
00376 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
00377 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
00378 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
00379 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
00380 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
00381 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_POINT );
00382 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
00383 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
00384 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
00385 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
00386 m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
00387 m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
00388
00389 if(which==0)
00390 m_pd3dDevice->EndStateBlock( &m_dwSavedStateBlock );
00391 else
00392 m_pd3dDevice->EndStateBlock( &m_dwDrawTextStateBlock );
00393 }
00394
00395 return S_OK;
00396 }
00397
00398
00399
00400
00401
00402
00403 HRESULT CD3DFont::InvalidateDeviceObjects() {
00404 HRESULT hr;
00405
00406 PRINT_REFCNT(dxgsg8,m_pd3dDevice);
00407
00408 if(IS_VALID_PTR(m_pd3dDevice)) {
00409
00410
00411 IDirect3DVertexBuffer8 *pStreamData=NULL;
00412 UINT StreamStride;
00413 hr = m_pd3dDevice->GetStreamSource(0,&pStreamData,&StreamStride);
00414 SAFE_RELEASE(pStreamData);
00415 if(pStreamData==m_pVB)
00416 hr = m_pd3dDevice->SetStreamSource(0,NULL,0);
00417 }
00418
00419 PRINT_REFCNT(dxgsg8,m_pVB);
00420
00421 RELEASE(m_pVB,dxgsg8,"d3dfont VB",RELEASE_ONCE);
00422
00423 PRINT_REFCNT(dxgsg8,m_pd3dDevice);
00424
00425
00426 if(m_pd3dDevice) {
00427 assert(IS_VALID_PTR(m_pd3dDevice));
00428 if(m_dwSavedStateBlock)
00429 m_pd3dDevice->DeleteStateBlock( m_dwSavedStateBlock );
00430 if(m_dwDrawTextStateBlock)
00431 m_pd3dDevice->DeleteStateBlock( m_dwDrawTextStateBlock );
00432 }
00433
00434 PRINT_REFCNT(dxgsg8,m_pd3dDevice);
00435
00436 m_dwSavedStateBlock = NULL;
00437 m_dwDrawTextStateBlock = NULL;
00438
00439 return S_OK;
00440 }
00441
00442
00443
00444
00445
00446
00447 HRESULT CD3DFont::DeleteDeviceObjects() {
00448 PRINT_REFCNT(dxgsg8,m_pd3dDevice);
00449
00450 InvalidateDeviceObjects();
00451
00452 SAFE_RELEASE( m_pTexture );
00453
00454 PRINT_REFCNT(dxgsg8,m_pd3dDevice);
00455
00456 m_pd3dDevice = NULL;
00457
00458 return S_OK;
00459 }
00460
00461
00462
00463
00464
00465
00466 HRESULT CD3DFont::GetTextExtent( TCHAR* strText, SIZE* pSize ) {
00467 if(NULL==strText || NULL==pSize)
00468 return E_FAIL;
00469
00470 FLOAT fRowWidth = 0.0f;
00471 FLOAT fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
00472 FLOAT fWidth = 0.0f;
00473 FLOAT fHeight = fRowHeight;
00474
00475 while(*strText) {
00476 TCHAR c = *strText++;
00477
00478 if(c == _T('\n')) {
00479 fRowWidth = 0.0f;
00480 fHeight += fRowHeight;
00481 }
00482 if(c < _T(' '))
00483 continue;
00484
00485 FLOAT tx1 = m_fTexCoords[c-32][0];
00486 FLOAT tx2 = m_fTexCoords[c-32][2];
00487
00488 fRowWidth += (tx2-tx1)*m_dwTexWidth;
00489
00490 if(fRowWidth > fWidth)
00491 fWidth = fRowWidth;
00492 }
00493
00494 pSize->cx = (int)fWidth;
00495 pSize->cy = (int)fHeight;
00496
00497 return S_OK;
00498 }
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 HRESULT CD3DFont::DrawTextScaled( FLOAT x, FLOAT y, FLOAT z,
00509 FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
00510 TCHAR* strText, DWORD dwFlags ) {
00511 if(m_pd3dDevice == NULL)
00512 return E_FAIL;
00513
00514 HRESULT hr ;
00515 if(m_bBeginText) {
00516 hr = DeferedDrawTextScaled ( x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ;
00517 } else {
00518 BeginText ( ) ;
00519 hr = DeferedDrawTextScaled ( x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ;
00520 if(! FAILED ( hr ))
00521 EndText ( ) ;
00522 } ;
00523
00524 return hr ;
00525 }
00526
00527
00528
00529
00530
00531 HRESULT CD3DFont::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor,
00532 TCHAR* strText, DWORD dwFlags ) {
00533 if(m_pd3dDevice == NULL)
00534 return E_FAIL;
00535
00536 HRESULT hr ;
00537 if(m_bBeginText) {
00538 hr = DeferedDrawText ( sx, sy, dwColor, strText, dwFlags ) ;
00539 } else {
00540 BeginText();
00541 hr = DeferedDrawText ( sx, sy, dwColor, strText, dwFlags ) ;
00542 if(! FAILED ( hr ))
00543 EndText ( ) ;
00544 } ;
00545
00546 return hr ;
00547 }
00548
00549
00550 void CD3DFont::ClearBeginEndData ( void ) {
00551 m_nDeferedCalls = 0 ;
00552 m_TextBuffer [ 0 ] = 0 ;
00553 m_pTextBuffer = & m_TextBuffer [ 0 ] ;
00554 }
00555
00556 HRESULT CD3DFont::BeginText ( void ) {
00557 m_bBeginText = true ;
00558 ClearBeginEndData() ;
00559
00560 return S_OK ;
00561 }
00562
00563 HRESULT CD3DFont::DeferedDrawTextScaled
00564 ( FLOAT x, FLOAT y, FLOAT z,
00565 FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
00566 TCHAR* strText, DWORD dwFlags ) {
00567 return
00568 DeferedDraw ( true , x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ;
00569 }
00570
00571 HRESULT CD3DFont::DeferedDrawText
00572 ( FLOAT x, FLOAT y, DWORD dwColor,
00573 TCHAR* strText, DWORD dwFlags ) {
00574 return
00575 DeferedDraw ( false , x, y, 0.0f , 0.0f , 0.0f , dwColor, strText, dwFlags ) ;
00576 }
00577
00578 HRESULT CD3DFont::DeferedDraw
00579 ( bool bScaled ,
00580 FLOAT x, FLOAT y, FLOAT z,
00581 FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
00582 TCHAR* strText, DWORD dwFlags ) {
00583 if(m_nDeferedCalls >= MaxCalls) {
00584 dxgsg8_cat.error() << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n";
00585 return E_FAIL ;
00586 }
00587
00588
00589
00590
00591 int nStrLen = strlen ( strText ) + 1 ;
00592 int nUsed = m_pTextBuffer - & m_pTextBuffer [ 0 ] ;
00593 if(nUsed + nStrLen > TextBufferLength) {
00594 dxgsg8_cat.error() << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n";
00595 return E_FAIL ;
00596 }
00597
00598 strcpy ( m_pTextBuffer , strText ) ;
00599 m_DTArgs [ m_nDeferedCalls ].m_strText = m_pTextBuffer ;
00600 m_pTextBuffer += nStrLen ;
00601
00602 m_DTArgs [ m_nDeferedCalls ].m_bScaled = bScaled ;
00603 m_DTArgs [ m_nDeferedCalls ].m_x = x ;
00604 m_DTArgs [ m_nDeferedCalls ].m_y = y ;
00605 m_DTArgs [ m_nDeferedCalls ].m_z = z ;
00606 m_DTArgs [ m_nDeferedCalls ].m_fXScale = fXScale ;
00607 m_DTArgs [ m_nDeferedCalls ].m_fYScale = fYScale ;
00608 m_DTArgs [ m_nDeferedCalls ].m_dwColor = dwColor ;
00609 m_DTArgs [ m_nDeferedCalls ].m_dwFlags = dwFlags ;
00610
00611 m_nDeferedCalls ++ ;
00612
00613 return S_OK ;
00614 }
00615
00616 HRESULT CD3DFont::EndText ( void ) {
00617 if(m_pd3dDevice == NULL)
00618 return E_FAIL;
00619 HRESULT hr;
00620
00621 assert(IS_VALID_PTR(m_pVB));
00622
00623 DWORD hSavedVertexShader,hSavedPixelShader;
00624 UINT SavedStreamStride;
00625 IDirect3DVertexBuffer8 *pSavedStreamData=NULL;
00626
00627 hr = m_pd3dDevice->GetVertexShader(&hSavedVertexShader);
00628 hr = m_pd3dDevice->GetPixelShader(&hSavedPixelShader);
00629
00630
00631 hr = m_pd3dDevice->CaptureStateBlock( m_dwSavedStateBlock );
00632 hr = m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
00633 if(hSavedVertexShader!=D3DFVF_FONT2DVERTEX)
00634 hr = m_pd3dDevice->SetVertexShader(D3DFVF_FONT2DVERTEX);
00635 if(hSavedPixelShader!=NULL)
00636 hr = m_pd3dDevice->SetPixelShader(NULL);
00637
00638 hr = m_pd3dDevice->GetStreamSource(0,&pSavedStreamData,&SavedStreamStride);
00639 if(FAILED(hr)) {
00640 dxgsg8_cat.error() << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr);
00641 return E_FAIL;
00642 }
00643
00644
00645 SAFE_RELEASE(pSavedStreamData);
00646
00647 if((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX))) {
00648 hr = m_pd3dDevice->SetStreamSource(0,m_pVB,sizeof(FONT2DVERTEX));
00649 if(FAILED(hr)) {
00650 dxgsg8_cat.error() << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr);
00651 return E_FAIL;
00652 }
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 bool bFiltered = false ;
00665 for(UINT i = 0 ; i < m_nDeferedCalls ; ++ i) {
00666 DWORD dwFlags = m_DTArgs [ i ].m_dwFlags ;
00667 if(dwFlags & D3DFONT_FILTERED) {
00668 bFiltered = true ;
00669 break ;
00670 }
00671 } ;
00672 if(bFiltered) {
00673 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
00674 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
00675 };
00676
00677
00678 D3DVIEWPORT8 vp;
00679 m_pd3dDevice->GetViewport( &vp );
00680 FLOAT fLineHeight = ( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight;
00681
00682
00683 FONT2DVERTEX* pVertices;
00684 DWORD dwNumTriangles = 0L;
00685 m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
00686
00687 bool bItalic = 0 != ( m_dwFontFlags & D3DFONT_ITALIC ) ;
00688
00689 for(UINT i = 0 ; i < m_nDeferedCalls ; ++ i) {
00690 bool bScaled = m_DTArgs [ i ].m_bScaled ;
00691 FLOAT x = m_DTArgs [ i ].m_x ;
00692 FLOAT y = m_DTArgs [ i ].m_y ;
00693 FLOAT z = m_DTArgs [ i ].m_z ;
00694 FLOAT fXScale = m_DTArgs [ i ].m_fXScale ;
00695 FLOAT fYScale = m_DTArgs [ i ].m_fYScale ;
00696 DWORD dwColor = m_DTArgs [ i ].m_dwColor ;
00697 TCHAR * strText = m_DTArgs [ i ].m_strText ;
00698
00699 if(bScaled) {
00700
00701 FLOAT sx = (x+1.0f)*vp.Width/2;
00702 FLOAT sy = (y-1.0f)*vp.Height/2;
00703 FLOAT sz = z;
00704 FLOAT rhw = 1.0f;
00705 FLOAT fStartX = sx;
00706
00707 FLOAT fBend = 0.0f ;
00708 if(bItalic)
00709 fBend = fYScale*vp.Height / 4.0f ;
00710
00711 while(*strText) {
00712 TCHAR c = *strText++;
00713
00714 if(c == _T('\n')) {
00715 sx = fStartX;
00716 sy += fYScale*vp.Height;
00717 }
00718 if(c < _T(' '))
00719 continue;
00720
00721 FLOAT tx1 = m_fTexCoords[c-32][0];
00722 FLOAT ty1 = m_fTexCoords[c-32][1];
00723 FLOAT tx2 = m_fTexCoords[c-32][2];
00724 FLOAT ty2 = m_fTexCoords[c-32][3];
00725
00726 FLOAT w = (tx2-tx1)*m_dwTexWidth;
00727 FLOAT h = (ty2-ty1)*m_dwTexHeight;
00728
00729 w *= (fXScale*vp.Height)/fLineHeight;
00730 h *= (fYScale*vp.Height)/fLineHeight;
00731
00732 if(c != _T(' ')) {
00733 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx1, ty2 );
00734 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
00735 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
00736 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx2, ty1 );
00737 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
00738 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
00739 dwNumTriangles += 2;
00740
00741 if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
00742
00743 m_pVB->Unlock();
00744 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
00745 m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
00746 dwNumTriangles = 0L;
00747 }
00748 }
00749
00750 sx += w;
00751 } ;
00752 } else {
00753 FLOAT fBend = 0.0f ;
00754 if(bItalic)
00755 fBend = fLineHeight / 4.0f ;
00756
00757
00758 FLOAT sx = x ;
00759 FLOAT sy = y ;
00760
00761 FLOAT fStartX = sx;
00762 while(*strText) {
00763 TCHAR c = *strText++;
00764
00765 if(c == _T('\n')) {
00766 sx = fStartX ;
00767 sy += fLineHeight ;
00768 }
00769 if(c < _T(' '))
00770 continue;
00771
00772 FLOAT tx1 = m_fTexCoords[c-32][0];
00773 FLOAT ty1 = m_fTexCoords[c-32][1];
00774 FLOAT tx2 = m_fTexCoords[c-32][2];
00775 FLOAT ty2 = m_fTexCoords[c-32][3];
00776
00777 FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
00778 FLOAT h = (ty2-ty1) * m_dwTexHeight / m_fTextScale;
00779
00780 if(c != _T(' ')) {
00781 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 );
00782 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
00783 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
00784 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 );
00785 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
00786 *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
00787 dwNumTriangles += 2;
00788
00789 if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
00790
00791 m_pVB->Unlock();
00792 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
00793 pVertices = NULL;
00794 m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
00795 dwNumTriangles = 0L;
00796 }
00797 };
00798
00799 sx += w;
00800 } ;
00801
00802 } ;
00803
00804 } ;
00805
00806 m_bBeginText = false ;
00807 ClearBeginEndData ( ) ;
00808
00809
00810 m_pVB->Unlock();
00811 if(dwNumTriangles > 0)
00812 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
00813
00814
00815 m_pd3dDevice->ApplyStateBlock( m_dwSavedStateBlock );
00816 if((hSavedVertexShader!=NULL) && (hSavedVertexShader!=D3DFVF_FONT2DVERTEX))
00817 m_pd3dDevice->SetVertexShader(hSavedVertexShader);
00818 if(hSavedPixelShader!=NULL)
00819 m_pd3dDevice->SetPixelShader(hSavedPixelShader);
00820
00821 if(IS_VALID_PTR(pSavedStreamData) && ((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX)))) {
00822 hr = m_pd3dDevice->SetStreamSource(0,pSavedStreamData,SavedStreamStride);
00823 if(FAILED(hr)) {
00824 dxgsg8_cat.error() << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr);
00825 return E_FAIL;
00826 }
00827 pSavedStreamData->Release();
00828 }
00829
00830 return S_OK;
00831 }
00832
00833 #if 0
00834
00835
00836
00837
00838
00839 HRESULT CD3DFont::Render3DText( TCHAR* strText, DWORD dwFlags ) {
00840 if(m_pd3dDevice == NULL)
00841 return E_FAIL;
00842
00843
00844 m_pd3dDevice->CaptureStateBlock( m_dwSavedStateBlock );
00845 m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
00846 m_pd3dDevice->SetVertexShader( D3DFVF_FONT3DVERTEX );
00847 m_pd3dDevice->SetPixelShader( NULL );
00848 m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(FONT3DVERTEX) );
00849
00850
00851 if(dwFlags & D3DFONT_FILTERED) {
00852 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
00853 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
00854 }
00855
00856
00857 FLOAT x = 0.0f;
00858 FLOAT y = 0.0f;
00859
00860
00861 if(dwFlags & D3DFONT_CENTERED) {
00862 SIZE sz;
00863 GetTextExtent( strText, &sz );
00864 x = -(((FLOAT)sz.cx)/10.0f)/2.0f;
00865 y = -(((FLOAT)sz.cy)/10.0f)/2.0f;
00866 }
00867
00868
00869 if(dwFlags & D3DFONT_TWOSIDED)
00870 m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
00871
00872 FLOAT fStartX = x;
00873 TCHAR c;
00874
00875
00876 FONT3DVERTEX* pVertices;
00877
00878 DWORD dwNumTriangles = 0L;
00879 m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
00880
00881 bool bItalic = 0 != ( m_dwFontFlags & D3DFONT_ITALIC ) ;
00882 FLOAT fBend = 0.0f ;
00883 if(bItalic)
00884 fBend = ( ( m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f ) / 4.0f ;
00885
00886 while(c = *strText++) {
00887 if(c == '\n') {
00888 x = fStartX;
00889 y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
00890 }
00891 if(c < 32)
00892 continue;
00893
00894 FLOAT tx1 = m_fTexCoords[c-32][0];
00895 FLOAT ty1 = m_fTexCoords[c-32][1];
00896 FLOAT tx2 = m_fTexCoords[c-32][2];
00897 FLOAT ty2 = m_fTexCoords[c-32][3];
00898
00899 FLOAT w = (tx2-tx1) * m_dwTexWidth / ( 10.0f * m_fTextScale );
00900 FLOAT h = (ty2-ty1) * m_dwTexHeight / ( 10.0f * m_fTextScale );
00901
00902 if(c != _T(' ')) {
00903 *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+0,0), D3DXVECTOR3(0,0,-1), tx1, ty2 );
00904 *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0 + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
00905 *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
00906 *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx2, ty1 );
00907 *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
00908 *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0 + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
00909 dwNumTriangles += 2;
00910
00911 if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
00912
00913 m_pVB->Unlock();
00914 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
00915 m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
00916 dwNumTriangles = 0L;
00917 }
00918 }
00919
00920 x += w;
00921 }
00922
00923
00924 m_pVB->Unlock();
00925 if(dwNumTriangles > 0)
00926 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
00927
00928
00929 m_pd3dDevice->ApplyStateBlock( m_dwSavedStateBlock );
00930
00931 return S_OK;
00932 }
00933 #endif