|
|
@@ -1,935 +0,0 @@
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// File: D3DFont.cpp
|
|
|
-//
|
|
|
-// Desc: Texture-based font class
|
|
|
-// modified from a modified version of DXSDK CD3DFont from http://www.lafaqmfc.com/directx.htm
|
|
|
-// Note that this is faster than ID3DXFont, which calls GDI in Draw()
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-#ifndef STRICT
|
|
|
-#define STRICT
|
|
|
-#endif
|
|
|
-
|
|
|
-#include "dxgsg8base.h"
|
|
|
-#include <stdio.h>
|
|
|
-#include <tchar.h>
|
|
|
-#include <d3dx8.h>
|
|
|
-#include "d3dfont8.h"
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Custom vertex types for rendering text
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-
|
|
|
-struct FONT2DVERTEX {
|
|
|
- D3DXVECTOR4 p; DWORD color; FLOAT tu, tv;
|
|
|
-};
|
|
|
-struct FONT3DVERTEX {
|
|
|
- D3DXVECTOR3 p; D3DXVECTOR3 n; FLOAT tu, tv;
|
|
|
-};
|
|
|
-
|
|
|
-inline FONT2DVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,
|
|
|
- FLOAT tu, FLOAT tv ) {
|
|
|
- FONT2DVERTEX v; v.p = p; v.color = color; v.tu = tu; v.tv = tv;
|
|
|
- return v;
|
|
|
-}
|
|
|
-
|
|
|
-inline FONT3DVERTEX InitFont3DVertex( const D3DXVECTOR3& p, const D3DXVECTOR3& n,
|
|
|
- FLOAT tu, FLOAT tv ) {
|
|
|
- FONT3DVERTEX v; v.p = p; v.n = n; v.tu = tu; v.tv = tv;
|
|
|
- return v;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: CD3DFont()
|
|
|
-// Desc: Font class constructor
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-CD3DFont::CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags ) {
|
|
|
- _tcscpy( m_strFontName, strFontName );
|
|
|
- m_dwFontHeight = dwHeight;
|
|
|
- m_dwFontFlags = dwFlags;
|
|
|
-
|
|
|
- m_pd3dDevice = NULL;
|
|
|
- m_pTexture = NULL;
|
|
|
- m_pVB = NULL;
|
|
|
-
|
|
|
- m_dwSavedStateBlock = NULL;
|
|
|
- m_dwDrawTextStateBlock = NULL;
|
|
|
-
|
|
|
- ClearBeginEndData ( ) ;
|
|
|
- m_bBeginText = false ;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: ~CD3DFont()
|
|
|
-// Desc: Font class destructor
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-CD3DFont::~CD3DFont() {
|
|
|
- DeleteDeviceObjects();
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: InitDeviceObjects()
|
|
|
-// Desc: Initializes device-dependent objects, including the vertex buffer used
|
|
|
-// for rendering text and the texture map which stores the font image.
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice ) {
|
|
|
- HRESULT hr;
|
|
|
-
|
|
|
- // Keep a local copy of the device
|
|
|
- m_pd3dDevice = pd3dDevice;
|
|
|
-
|
|
|
- // Establish the font and texture size
|
|
|
- m_fTextScale = 1.0f; // Draw fonts into texture without scaling
|
|
|
-
|
|
|
- // Large fonts need larger textures
|
|
|
- // We can be generous at this step, this is an estimate
|
|
|
- if(m_dwFontHeight > 40)
|
|
|
- m_dwTexWidth = m_dwTexHeight = 2048;
|
|
|
- else if(m_dwFontHeight > 32)
|
|
|
- m_dwTexWidth = m_dwTexHeight = 1024;
|
|
|
- else if(m_dwFontHeight > 16)
|
|
|
- m_dwTexWidth = m_dwTexHeight = 512;
|
|
|
- else
|
|
|
- m_dwTexWidth = m_dwTexHeight = 256;
|
|
|
-
|
|
|
- // Prepare to create a bitmap
|
|
|
- DWORD* pBitmapBits;
|
|
|
- BITMAPINFO bmi;
|
|
|
- ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
|
|
|
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
- bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
|
|
- bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
|
|
- bmi.bmiHeader.biPlanes = 1;
|
|
|
- bmi.bmiHeader.biCompression = BI_RGB;
|
|
|
- bmi.bmiHeader.biBitCount = 32;
|
|
|
-
|
|
|
- // Create a DC and a bitmap for the font
|
|
|
- HDC hDC = CreateCompatibleDC( NULL );
|
|
|
- HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
|
|
|
- (VOID**)&pBitmapBits, NULL, 0 );
|
|
|
- SetMapMode( hDC, MM_TEXT );
|
|
|
-
|
|
|
- // Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
|
|
- // antialiased font, but this is not guaranteed.
|
|
|
- INT nHeight = -MulDiv( m_dwFontHeight,
|
|
|
- (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
|
|
|
- DWORD dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
|
|
|
- DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE;
|
|
|
- HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold,
|
|
|
-
|
|
|
- FALSE , // dwItalic, // NO! We should not do that...
|
|
|
- // See below comment about GetTextExtentPoint32
|
|
|
-
|
|
|
- FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
|
|
- CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
|
|
- VARIABLE_PITCH, m_strFontName );
|
|
|
- if(NULL==hFont) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont InitDeviceObjects(): initial CreateFont failed! GetLastError=" << GetLastError() << endl;
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
-
|
|
|
- HBITMAP hbmOld = ( HBITMAP ) SelectObject ( hDC, hbmBitmap );
|
|
|
- HFONT hfOld = ( HFONT ) SelectObject ( hDC, hFont );
|
|
|
-
|
|
|
- // Set text properties
|
|
|
- SetTextColor( hDC, RGB(255,255,255) );
|
|
|
- SetBkColor( hDC, 0x00000000 );
|
|
|
- SetTextAlign( hDC, TA_TOP );
|
|
|
-
|
|
|
- // First Loop through all printable characters
|
|
|
- // in order to determine the smallest necessary texture
|
|
|
- DWORD x = 0;
|
|
|
- DWORD y = 0;
|
|
|
- TCHAR str[2] = _T("x");
|
|
|
- SIZE size;
|
|
|
- SIZE sizes [ 127 - 32 ] ;
|
|
|
-
|
|
|
- TCHAR c;
|
|
|
- for(c=32; c<127; c++) {
|
|
|
- str[0] = c;
|
|
|
- // GetTextExtentPoint32 does not care that the font is Italic or not, it will
|
|
|
- // return the same value. However, if we specify an Italic font, the output
|
|
|
- // on the bitmap will use more pixels.
|
|
|
- // If the font is Italic we have to output the standard character
|
|
|
- // and bend our vertices.
|
|
|
- GetTextExtentPoint32 ( hDC, str, 1, & sizes [ c - 32 ] );
|
|
|
- } ;
|
|
|
-
|
|
|
- static DWORD TexturesSizes [ 5 ] = { 128 , 256 , 512 , 1024 , 2048} ;
|
|
|
- DWORD dwTexSize = 0 ;
|
|
|
- for(DWORD iTex = 0 ; iTex < 5 ; ++ iTex) {
|
|
|
- // fake the tex coord loop calculation
|
|
|
- x = 0 ;
|
|
|
- y = 0 ;
|
|
|
- for(TCHAR c=32; c<127; c++) {
|
|
|
- if((DWORD)( x + sizes[ c - 32 ].cx+1) > TexturesSizes [ iTex ]) {
|
|
|
- x = 0;
|
|
|
- y += sizes[ c - 32 ].cy+1;
|
|
|
- // new y size
|
|
|
- if((DWORD) ( y + sizes[ 0 ].cy + 1 ) >= TexturesSizes [ iTex ]) {
|
|
|
- // does not fit, let's try a larger one
|
|
|
- break ;
|
|
|
- };
|
|
|
- };
|
|
|
- x += sizes[ c - 32 ].cx + 2 ;
|
|
|
- } ;
|
|
|
-
|
|
|
- if((DWORD) ( y + sizes[ 0 ].cy + 1 ) < TexturesSizes [ iTex ]) {
|
|
|
- // Yahoo! it fits!
|
|
|
- dwTexSize = TexturesSizes [ iTex ] ;
|
|
|
- break ;
|
|
|
- };
|
|
|
- } ;
|
|
|
-
|
|
|
- m_dwTexWidth = m_dwTexHeight = dwTexSize ;
|
|
|
-
|
|
|
- // Select old objects ( added )
|
|
|
- // Is this needed for compatible DCs?
|
|
|
- // The old handles are not not NULL, so it is done "by the book"
|
|
|
- SelectObject ( hDC, hbmOld );
|
|
|
- SelectObject ( hDC, hfOld );
|
|
|
-
|
|
|
- // delete our gdi objects
|
|
|
- DeleteObject( hbmBitmap );
|
|
|
- DeleteObject( hFont );
|
|
|
- DeleteDC( hDC );
|
|
|
-
|
|
|
- // moved here to allow deletion of GDI objects
|
|
|
- if(dwTexSize == 0) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n";
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
-
|
|
|
- // Re-Create new GDI stuff with the optimal size
|
|
|
- //
|
|
|
- // Prepare to create a bitmap
|
|
|
- ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
|
|
|
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
- bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
|
|
|
- bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
|
|
|
- bmi.bmiHeader.biPlanes = 1;
|
|
|
- bmi.bmiHeader.biCompression = BI_RGB;
|
|
|
- bmi.bmiHeader.biBitCount = 32;
|
|
|
-
|
|
|
- // Create a DC and a bitmap for the font
|
|
|
- hDC = CreateCompatibleDC( NULL );
|
|
|
- hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
|
|
|
- (VOID**)&pBitmapBits, NULL, 0 );
|
|
|
- SetMapMode( hDC, MM_TEXT );
|
|
|
-
|
|
|
- // Create a font. By specifying ANTIALIASED_QUALITY, we might get an
|
|
|
- // antialiased font, but this is not guaranteed.
|
|
|
- nHeight = -MulDiv( m_dwFontHeight,
|
|
|
- (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
|
|
|
- dwBold = (m_dwFontFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL;
|
|
|
- dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE : FALSE;
|
|
|
- hFont = CreateFont( nHeight, 0, 0, 0, dwBold,
|
|
|
- FALSE , // was dwItalic, // see above
|
|
|
- FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
|
|
- CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
|
|
- VARIABLE_PITCH, m_strFontName );
|
|
|
-
|
|
|
- if(NULL==hFont) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont InitDeviceObjects(): optimal CreateFont failed! GetLastError=" << GetLastError() << endl;
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
-
|
|
|
- hbmOld = ( HBITMAP ) SelectObject ( hDC, hbmBitmap );
|
|
|
- hfOld = ( HFONT ) SelectObject ( hDC, hFont );
|
|
|
-
|
|
|
- // Set text properties
|
|
|
- SetTextColor( hDC, RGB(255,255,255) );
|
|
|
- SetBkColor( hDC, 0x00000000 );
|
|
|
- SetTextAlign( hDC, TA_TOP );
|
|
|
-
|
|
|
- // If requested texture is too big, use a smaller texture and smaller font,
|
|
|
- // and scale up when rendering.
|
|
|
- D3DCAPS8 d3dCaps;
|
|
|
- m_pd3dDevice->GetDeviceCaps( &d3dCaps );
|
|
|
-
|
|
|
- if(m_dwTexWidth > d3dCaps.MaxTextureWidth) {
|
|
|
- m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwTexWidth;
|
|
|
- m_dwTexWidth = m_dwTexHeight = d3dCaps.MaxTextureWidth;
|
|
|
- };
|
|
|
-
|
|
|
- // Create a new texture for the font
|
|
|
- hr = m_pd3dDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
|
|
|
- 0, D3DFMT_A4R4G4B4,
|
|
|
- D3DPOOL_MANAGED, &m_pTexture );
|
|
|
-
|
|
|
- if(FAILED(hr)) {
|
|
|
- SelectObject ( hDC, hbmOld );
|
|
|
- SelectObject ( hDC, hfOld );
|
|
|
-
|
|
|
- DeleteObject( hbmBitmap );
|
|
|
- DeleteObject( hFont );
|
|
|
- DeleteDC( hDC );
|
|
|
-
|
|
|
- dxgsg8_cat.error() << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr);
|
|
|
- return hr;
|
|
|
- };
|
|
|
-
|
|
|
- // Loop through all printable character and output them to the bitmap..
|
|
|
- // Meanwhile, keep track of the corresponding tex coords for each character.
|
|
|
- x = 0 ;
|
|
|
- y = 0 ;
|
|
|
-
|
|
|
- for(c=32; c<127; c++) {
|
|
|
- str[0] = c;
|
|
|
- GetTextExtentPoint32( hDC, str, 1, &size );
|
|
|
- if((DWORD)(x+size.cx+1) > m_dwTexWidth) {
|
|
|
- x = 0;
|
|
|
- y += size.cy+1;
|
|
|
- }
|
|
|
-
|
|
|
- // We need one pixel on both sides
|
|
|
-
|
|
|
- // plus one here for one pixel on the left
|
|
|
- ExtTextOut( hDC, x + 1, y, ETO_OPAQUE, NULL, str, 1, NULL );
|
|
|
-
|
|
|
- m_fTexCoords[c-32][0] = ( (FLOAT) x + 0.5f ) / m_dwTexWidth ;
|
|
|
- m_fTexCoords[c-32][1] = ( (FLOAT) y + 0.5f ) / m_dwTexHeight ;
|
|
|
- m_fTexCoords[c-32][2] = ( (FLOAT) x + 0.5f + size.cx ) / m_dwTexWidth;
|
|
|
- m_fTexCoords[c-32][3] = ( (FLOAT) y + 0.5f + size.cy ) / m_dwTexHeight;
|
|
|
-
|
|
|
- // plus two here because we also need one more pixel on the right side
|
|
|
- x += size.cx + 2 ;
|
|
|
- }
|
|
|
-
|
|
|
- // Lock the surface and write the alpha values for the set pixels
|
|
|
- D3DLOCKED_RECT d3dlr;
|
|
|
- m_pTexture->LockRect( 0, &d3dlr, 0, 0 );
|
|
|
- BYTE* pDstRow = (BYTE*)d3dlr.pBits;
|
|
|
- WORD* pDst16;
|
|
|
- BYTE bAlpha; // 4-bit measure of pixel intensity
|
|
|
-
|
|
|
- for(y=0; y < m_dwTexHeight; y++) {
|
|
|
- pDst16 = (WORD*)pDstRow;
|
|
|
- for(x=0; x < m_dwTexWidth; x++) {
|
|
|
- bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
|
|
|
- if(bAlpha > 0) {
|
|
|
- *pDst16++ = (bAlpha << 12) | 0x0fff;
|
|
|
- } else {
|
|
|
- *pDst16++ = 0x0000;
|
|
|
- }
|
|
|
- }
|
|
|
- pDstRow += d3dlr.Pitch;
|
|
|
- }
|
|
|
-
|
|
|
- // Done updating texture, so clean up used objects
|
|
|
- m_pTexture->UnlockRect(0);
|
|
|
-
|
|
|
- SelectObject ( hDC, hbmOld );
|
|
|
- SelectObject ( hDC, hfOld );
|
|
|
-
|
|
|
- DeleteObject( hbmBitmap );
|
|
|
- DeleteObject( hFont );
|
|
|
- DeleteDC( hDC );
|
|
|
-
|
|
|
- return RestoreDeviceObjects();
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: RestoreDeviceObjects()
|
|
|
-// Desc:
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::RestoreDeviceObjects() {
|
|
|
- HRESULT hr;
|
|
|
-
|
|
|
- // Create vertex buffer for the letters
|
|
|
- if(FAILED( hr = m_pd3dDevice->CreateVertexBuffer(
|
|
|
- // can be rendered 3d
|
|
|
- MAX_NUM_VERTICES*sizeof(FONT3DVERTEX /*FONT2DVERTEX */ ),
|
|
|
- D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
|
|
|
- D3DPOOL_DEFAULT, // D3DUSAGE_DYNAMIC makes D3DPOOL_MANAGED impossible
|
|
|
- &m_pVB ) )) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr);
|
|
|
- return hr;
|
|
|
- }
|
|
|
-
|
|
|
- PRINT_REFCNT(dxgsg8,m_pd3dDevice);
|
|
|
-
|
|
|
- // Create the state blocks for rendering text
|
|
|
- for(UINT which=0; which<2; which++) {
|
|
|
- m_pd3dDevice->BeginStateBlock();
|
|
|
- m_pd3dDevice->SetTexture( 0, m_pTexture );
|
|
|
-
|
|
|
- if(D3DFONT_ZENABLE & m_dwFontFlags)
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
|
|
|
- else
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
|
|
|
-
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_EDGEANTIALIAS, FALSE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, FALSE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_POINT );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
|
|
|
- m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
|
|
|
-
|
|
|
- if(which==0)
|
|
|
- m_pd3dDevice->EndStateBlock( &m_dwSavedStateBlock );
|
|
|
- else
|
|
|
- m_pd3dDevice->EndStateBlock( &m_dwDrawTextStateBlock );
|
|
|
- }
|
|
|
-
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: InvalidateDeviceObjects()
|
|
|
-// Desc: Destroys all device-dependent objects
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::InvalidateDeviceObjects() {
|
|
|
- HRESULT hr;
|
|
|
-
|
|
|
- PRINT_REFCNT(dxgsg8,m_pd3dDevice);
|
|
|
-
|
|
|
- if(IS_VALID_PTR(m_pd3dDevice)) {
|
|
|
- // undo SetStreamSource before releasing VB
|
|
|
-
|
|
|
- IDirect3DVertexBuffer8 *pStreamData=NULL;
|
|
|
- UINT StreamStride;
|
|
|
- hr = m_pd3dDevice->GetStreamSource(0,&pStreamData,&StreamStride);
|
|
|
- SAFE_RELEASE(pStreamData); // undo GetStreamSource AddRef
|
|
|
- if(pStreamData==m_pVB)
|
|
|
- hr = m_pd3dDevice->SetStreamSource(0,NULL,0);
|
|
|
- }
|
|
|
-
|
|
|
- PRINT_REFCNT(dxgsg8,m_pVB);
|
|
|
-
|
|
|
- RELEASE(m_pVB,dxgsg8,"d3dfont VB",RELEASE_ONCE);
|
|
|
-
|
|
|
- PRINT_REFCNT(dxgsg8,m_pd3dDevice);
|
|
|
-
|
|
|
- // Delete the state blocks
|
|
|
- if(m_pd3dDevice) {
|
|
|
- assert(IS_VALID_PTR(m_pd3dDevice));
|
|
|
- if(m_dwSavedStateBlock)
|
|
|
- m_pd3dDevice->DeleteStateBlock( m_dwSavedStateBlock );
|
|
|
- if(m_dwDrawTextStateBlock)
|
|
|
- m_pd3dDevice->DeleteStateBlock( m_dwDrawTextStateBlock );
|
|
|
- }
|
|
|
-
|
|
|
- PRINT_REFCNT(dxgsg8,m_pd3dDevice);
|
|
|
-
|
|
|
- m_dwSavedStateBlock = NULL;
|
|
|
- m_dwDrawTextStateBlock = NULL;
|
|
|
-
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: DeleteDeviceObjects()
|
|
|
-// Desc: Destroys all device-dependent objects
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::DeleteDeviceObjects() {
|
|
|
- PRINT_REFCNT(dxgsg8,m_pd3dDevice);
|
|
|
-
|
|
|
- InvalidateDeviceObjects();
|
|
|
-
|
|
|
- SAFE_RELEASE( m_pTexture );
|
|
|
-
|
|
|
- PRINT_REFCNT(dxgsg8,m_pd3dDevice);
|
|
|
-
|
|
|
- m_pd3dDevice = NULL;
|
|
|
-
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: GetTextExtent()
|
|
|
-// Desc: Get the dimensions of a text string
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::GetTextExtent( TCHAR* strText, SIZE* pSize ) {
|
|
|
- if(NULL==strText || NULL==pSize)
|
|
|
- return E_FAIL;
|
|
|
-
|
|
|
- FLOAT fRowWidth = 0.0f;
|
|
|
- FLOAT fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
|
|
|
- FLOAT fWidth = 0.0f;
|
|
|
- FLOAT fHeight = fRowHeight;
|
|
|
-
|
|
|
- while(*strText) {
|
|
|
- TCHAR c = *strText++;
|
|
|
-
|
|
|
- if(c == _T('\n')) {
|
|
|
- fRowWidth = 0.0f;
|
|
|
- fHeight += fRowHeight;
|
|
|
- }
|
|
|
- if(c < _T(' '))
|
|
|
- continue;
|
|
|
-
|
|
|
- FLOAT tx1 = m_fTexCoords[c-32][0];
|
|
|
- FLOAT tx2 = m_fTexCoords[c-32][2];
|
|
|
-
|
|
|
- fRowWidth += (tx2-tx1)*m_dwTexWidth;
|
|
|
-
|
|
|
- if(fRowWidth > fWidth)
|
|
|
- fWidth = fRowWidth;
|
|
|
- }
|
|
|
-
|
|
|
- pSize->cx = (int)fWidth;
|
|
|
- pSize->cy = (int)fHeight;
|
|
|
-
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: DrawTextScaled()
|
|
|
-// Desc: Draws scaled 2D text. Note that x and y are in viewport coordinates
|
|
|
-// (ranging from -1 to +1). fXScale and fYScale are the size fraction
|
|
|
-// relative to the entire viewport. For example, a fXScale of 0.25 is
|
|
|
-// 1/8th of the screen width. This allows you to output text at a fixed
|
|
|
-// fraction of the viewport, even if the screen or window size changes.
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::DrawTextScaled( FLOAT x, FLOAT y, FLOAT z,
|
|
|
- FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
|
|
|
- TCHAR* strText, DWORD dwFlags ) {
|
|
|
- if(m_pd3dDevice == NULL)
|
|
|
- return E_FAIL;
|
|
|
-
|
|
|
- HRESULT hr ;
|
|
|
- if(m_bBeginText) {
|
|
|
- hr = DeferedDrawTextScaled ( x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ;
|
|
|
- } else {
|
|
|
- BeginText ( ) ;
|
|
|
- hr = DeferedDrawTextScaled ( x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ;
|
|
|
- if(! FAILED ( hr ))
|
|
|
- EndText ( ) ;
|
|
|
- } ;
|
|
|
-
|
|
|
- return hr ;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: DrawText()
|
|
|
-// Desc: Draws 2D text
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor,
|
|
|
- TCHAR* strText, DWORD dwFlags ) {
|
|
|
- if(m_pd3dDevice == NULL)
|
|
|
- return E_FAIL;
|
|
|
-
|
|
|
- HRESULT hr ;
|
|
|
- if(m_bBeginText) {
|
|
|
- hr = DeferedDrawText ( sx, sy, dwColor, strText, dwFlags ) ;
|
|
|
- } else {
|
|
|
- BeginText();
|
|
|
- hr = DeferedDrawText ( sx, sy, dwColor, strText, dwFlags ) ;
|
|
|
- if(! FAILED ( hr ))
|
|
|
- EndText ( ) ;
|
|
|
- } ;
|
|
|
-
|
|
|
- return hr ;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void CD3DFont::ClearBeginEndData ( void ) {
|
|
|
- m_nDeferedCalls = 0 ;
|
|
|
- m_TextBuffer [ 0 ] = 0 ;
|
|
|
- m_pTextBuffer = & m_TextBuffer [ 0 ] ;
|
|
|
-}
|
|
|
-
|
|
|
-HRESULT CD3DFont::BeginText ( void ) {
|
|
|
- m_bBeginText = true ;
|
|
|
- ClearBeginEndData() ;
|
|
|
-
|
|
|
- return S_OK ;
|
|
|
-}
|
|
|
-
|
|
|
-HRESULT CD3DFont::DeferedDrawTextScaled
|
|
|
-( FLOAT x, FLOAT y, FLOAT z,
|
|
|
- FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
|
|
|
- TCHAR* strText, DWORD dwFlags ) {
|
|
|
- return
|
|
|
- DeferedDraw ( true , x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ;
|
|
|
-}
|
|
|
-
|
|
|
-HRESULT CD3DFont::DeferedDrawText
|
|
|
-( FLOAT x, FLOAT y, DWORD dwColor,
|
|
|
- TCHAR* strText, DWORD dwFlags ) {
|
|
|
- return
|
|
|
- DeferedDraw ( false , x, y, 0.0f , 0.0f , 0.0f , dwColor, strText, dwFlags ) ;
|
|
|
-}
|
|
|
-
|
|
|
-HRESULT CD3DFont::DeferedDraw
|
|
|
-( bool bScaled ,
|
|
|
- FLOAT x, FLOAT y, FLOAT z,
|
|
|
- FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
|
|
|
- TCHAR* strText, DWORD dwFlags ) {
|
|
|
- if(m_nDeferedCalls >= MaxCalls) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n";
|
|
|
- return E_FAIL ;
|
|
|
- }
|
|
|
-
|
|
|
- // we need to make a deep copy of the string
|
|
|
- // the user object might have fallen out of scope
|
|
|
- // when it will be time to render
|
|
|
- int nStrLen = strlen ( strText ) + 1 ;
|
|
|
- int nUsed = m_pTextBuffer - & m_pTextBuffer [ 0 ] ;
|
|
|
- if(nUsed + nStrLen > TextBufferLength) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n";
|
|
|
- return E_FAIL ;
|
|
|
- }
|
|
|
-
|
|
|
- strcpy ( m_pTextBuffer , strText ) ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_strText = m_pTextBuffer ;
|
|
|
- m_pTextBuffer += nStrLen ;
|
|
|
-
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_bScaled = bScaled ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_x = x ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_y = y ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_z = z ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_fXScale = fXScale ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_fYScale = fYScale ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_dwColor = dwColor ;
|
|
|
- m_DTArgs [ m_nDeferedCalls ].m_dwFlags = dwFlags ;
|
|
|
-
|
|
|
- m_nDeferedCalls ++ ;
|
|
|
-
|
|
|
- return S_OK ;
|
|
|
-}
|
|
|
-
|
|
|
-HRESULT CD3DFont::EndText ( void ) {
|
|
|
- if(m_pd3dDevice == NULL)
|
|
|
- return E_FAIL;
|
|
|
- HRESULT hr;
|
|
|
-
|
|
|
- assert(IS_VALID_PTR(m_pVB));
|
|
|
-
|
|
|
- DWORD hSavedVertexShader,hSavedPixelShader;
|
|
|
- UINT SavedStreamStride;
|
|
|
- IDirect3DVertexBuffer8 *pSavedStreamData=NULL;
|
|
|
-
|
|
|
- hr = m_pd3dDevice->GetVertexShader(&hSavedVertexShader);
|
|
|
- hr = m_pd3dDevice->GetPixelShader(&hSavedPixelShader);
|
|
|
-
|
|
|
- // Set up renderstate
|
|
|
- hr = m_pd3dDevice->CaptureStateBlock( m_dwSavedStateBlock );
|
|
|
- hr = m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
|
|
|
- if(hSavedVertexShader!=D3DFVF_FONT2DVERTEX)
|
|
|
- hr = m_pd3dDevice->SetVertexShader(D3DFVF_FONT2DVERTEX);
|
|
|
- if(hSavedPixelShader!=NULL)
|
|
|
- hr = m_pd3dDevice->SetPixelShader(NULL);
|
|
|
-
|
|
|
- hr = m_pd3dDevice->GetStreamSource(0,&pSavedStreamData,&SavedStreamStride);
|
|
|
- if(FAILED(hr)) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr);
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
-
|
|
|
- // undo GetStreamSource AddRef
|
|
|
- SAFE_RELEASE(pSavedStreamData);
|
|
|
-
|
|
|
- if((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX))) {
|
|
|
- hr = m_pd3dDevice->SetStreamSource(0,m_pVB,sizeof(FONT2DVERTEX));
|
|
|
- if(FAILED(hr)) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr);
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Set filter states
|
|
|
- //
|
|
|
- // filter if any in our list is specified filtered
|
|
|
- //
|
|
|
- // This functionality is different from the original D3DFont
|
|
|
- // but is a significant speed increase
|
|
|
- //
|
|
|
- // User will make another batch if necessary
|
|
|
- //
|
|
|
- bool bFiltered = false ;
|
|
|
- UINT i;
|
|
|
- for(i = 0 ; i < m_nDeferedCalls ; ++ i) {
|
|
|
- DWORD dwFlags = m_DTArgs [ i ].m_dwFlags ;
|
|
|
- if(dwFlags & D3DFONT_FILTERED) {
|
|
|
- bFiltered = true ;
|
|
|
- break ;
|
|
|
- }
|
|
|
- } ;
|
|
|
- if(bFiltered) {
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
|
|
- };
|
|
|
-
|
|
|
- // useless if nothing is scaled but should be fast enough
|
|
|
- D3DVIEWPORT8 vp;
|
|
|
- m_pd3dDevice->GetViewport( &vp );
|
|
|
- FLOAT fLineHeight = ( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight;
|
|
|
-
|
|
|
- // Fill vertex buffer
|
|
|
- FONT2DVERTEX* pVertices;
|
|
|
- DWORD dwNumTriangles = 0L;
|
|
|
- m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
|
|
|
-
|
|
|
- bool bItalic = 0 != ( m_dwFontFlags & D3DFONT_ITALIC ) ;
|
|
|
- // loop on our batched sets of arguments
|
|
|
- for(i = 0 ; i < m_nDeferedCalls ; ++ i) {
|
|
|
- bool bScaled = m_DTArgs [ i ].m_bScaled ;
|
|
|
- FLOAT x = m_DTArgs [ i ].m_x ;
|
|
|
- FLOAT y = m_DTArgs [ i ].m_y ;
|
|
|
- FLOAT z = m_DTArgs [ i ].m_z ;
|
|
|
- FLOAT fXScale = m_DTArgs [ i ].m_fXScale ;
|
|
|
- FLOAT fYScale = m_DTArgs [ i ].m_fYScale ;
|
|
|
- DWORD dwColor = m_DTArgs [ i ].m_dwColor ;
|
|
|
- TCHAR * strText = m_DTArgs [ i ].m_strText ;
|
|
|
-
|
|
|
- if(bScaled) {
|
|
|
-
|
|
|
- FLOAT sx = (x+1.0f)*vp.Width/2;
|
|
|
- FLOAT sy = (y-1.0f)*vp.Height/2;
|
|
|
- FLOAT sz = z;
|
|
|
- FLOAT rhw = 1.0f;
|
|
|
- FLOAT fStartX = sx;
|
|
|
-
|
|
|
- FLOAT fBend = 0.0f ;
|
|
|
- if(bItalic)
|
|
|
- fBend = fYScale*vp.Height / 4.0f ;
|
|
|
-
|
|
|
- while(*strText) {
|
|
|
- TCHAR c = *strText++;
|
|
|
-
|
|
|
- if(c == _T('\n')) {
|
|
|
- sx = fStartX;
|
|
|
- sy += fYScale*vp.Height;
|
|
|
- }
|
|
|
- if(c < _T(' '))
|
|
|
- continue;
|
|
|
-
|
|
|
- FLOAT tx1 = m_fTexCoords[c-32][0];
|
|
|
- FLOAT ty1 = m_fTexCoords[c-32][1];
|
|
|
- FLOAT tx2 = m_fTexCoords[c-32][2];
|
|
|
- FLOAT ty2 = m_fTexCoords[c-32][3];
|
|
|
-
|
|
|
- FLOAT w = (tx2-tx1)*m_dwTexWidth;
|
|
|
- FLOAT h = (ty2-ty1)*m_dwTexHeight;
|
|
|
-
|
|
|
- w *= (fXScale*vp.Height)/fLineHeight;
|
|
|
- h *= (fYScale*vp.Height)/fLineHeight;
|
|
|
-
|
|
|
- if(c != _T(' ')) {
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx1, ty2 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx2, ty1 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
|
|
|
- dwNumTriangles += 2;
|
|
|
-
|
|
|
- if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
|
|
|
- // Unlock, render, and relock the vertex buffer
|
|
|
- m_pVB->Unlock();
|
|
|
- m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
|
|
|
- m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
|
|
|
- dwNumTriangles = 0L;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- sx += w;
|
|
|
- } ;
|
|
|
- } else { // not scaled
|
|
|
- FLOAT fBend = 0.0f ;
|
|
|
- if(bItalic)
|
|
|
- fBend = fLineHeight / 4.0f ;
|
|
|
-
|
|
|
- // Lazy guy...
|
|
|
- FLOAT sx = x ;
|
|
|
- FLOAT sy = y ;
|
|
|
-
|
|
|
- FLOAT fStartX = sx;
|
|
|
- while(*strText) {
|
|
|
- TCHAR c = *strText++;
|
|
|
-
|
|
|
- if(c == _T('\n')) {
|
|
|
- sx = fStartX ;
|
|
|
- sy += fLineHeight ;
|
|
|
- }
|
|
|
- if(c < _T(' '))
|
|
|
- continue;
|
|
|
-
|
|
|
- FLOAT tx1 = m_fTexCoords[c-32][0];
|
|
|
- FLOAT ty1 = m_fTexCoords[c-32][1];
|
|
|
- FLOAT tx2 = m_fTexCoords[c-32][2];
|
|
|
- FLOAT ty2 = m_fTexCoords[c-32][3];
|
|
|
-
|
|
|
- FLOAT w = (tx2-tx1) * m_dwTexWidth / m_fTextScale;
|
|
|
- FLOAT h = (ty2-ty1) * m_dwTexHeight / m_fTextScale;
|
|
|
-
|
|
|
- if(c != _T(' ')) {
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
|
|
|
- *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
|
|
|
- dwNumTriangles += 2;
|
|
|
-
|
|
|
- if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
|
|
|
- // Unlock, render, and relock the vertex buffer
|
|
|
- m_pVB->Unlock();
|
|
|
- m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
|
|
|
- pVertices = NULL;
|
|
|
- m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
|
|
|
- dwNumTriangles = 0L;
|
|
|
- }
|
|
|
- }; // endif not blank
|
|
|
-
|
|
|
- sx += w;
|
|
|
- } ; // end while
|
|
|
-
|
|
|
- } ; // end if else scaled
|
|
|
-
|
|
|
- } ; // end for
|
|
|
-
|
|
|
- m_bBeginText = false ;
|
|
|
- ClearBeginEndData ( ) ;
|
|
|
-
|
|
|
- // Unlock and render the vertex buffer
|
|
|
- m_pVB->Unlock();
|
|
|
- if(dwNumTriangles > 0)
|
|
|
- m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
|
|
|
-
|
|
|
- // Restore the modified renderstates
|
|
|
- m_pd3dDevice->ApplyStateBlock( m_dwSavedStateBlock );
|
|
|
- if((hSavedVertexShader!=NULL) && (hSavedVertexShader!=D3DFVF_FONT2DVERTEX))
|
|
|
- m_pd3dDevice->SetVertexShader(hSavedVertexShader);
|
|
|
- if(hSavedPixelShader!=NULL)
|
|
|
- m_pd3dDevice->SetPixelShader(hSavedPixelShader);
|
|
|
-
|
|
|
- if(IS_VALID_PTR(pSavedStreamData) && ((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX)))) {
|
|
|
- hr = m_pd3dDevice->SetStreamSource(0,pSavedStreamData,SavedStreamStride);
|
|
|
- if(FAILED(hr)) {
|
|
|
- dxgsg8_cat.error() << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr);
|
|
|
- return E_FAIL;
|
|
|
- }
|
|
|
- pSavedStreamData->Release();
|
|
|
- }
|
|
|
-
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-
|
|
|
-#if 0
|
|
|
-// dont need this now
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Name: Render3DText()
|
|
|
-// Desc: Renders 3D text
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-HRESULT CD3DFont::Render3DText( TCHAR* strText, DWORD dwFlags ) {
|
|
|
- if(m_pd3dDevice == NULL)
|
|
|
- return E_FAIL;
|
|
|
-
|
|
|
- // Setup renderstate
|
|
|
- m_pd3dDevice->CaptureStateBlock( m_dwSavedStateBlock );
|
|
|
- m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
|
|
|
- m_pd3dDevice->SetVertexShader( D3DFVF_FONT3DVERTEX );
|
|
|
- m_pd3dDevice->SetPixelShader( NULL );
|
|
|
- m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(FONT3DVERTEX) );
|
|
|
-
|
|
|
- // Set filter states
|
|
|
- if(dwFlags & D3DFONT_FILTERED) {
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
|
|
- m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
|
|
- }
|
|
|
-
|
|
|
- // Position for each text element
|
|
|
- FLOAT x = 0.0f;
|
|
|
- FLOAT y = 0.0f;
|
|
|
-
|
|
|
- // Center the text block at the origin
|
|
|
- if(dwFlags & D3DFONT_CENTERED) {
|
|
|
- SIZE sz;
|
|
|
- GetTextExtent( strText, &sz );
|
|
|
- x = -(((FLOAT)sz.cx)/10.0f)/2.0f;
|
|
|
- y = -(((FLOAT)sz.cy)/10.0f)/2.0f;
|
|
|
- }
|
|
|
-
|
|
|
- // Turn off culling for two-sided text
|
|
|
- if(dwFlags & D3DFONT_TWOSIDED)
|
|
|
- m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
|
|
|
-
|
|
|
- FLOAT fStartX = x;
|
|
|
- TCHAR c;
|
|
|
-
|
|
|
- // Fill vertex buffer
|
|
|
- FONT3DVERTEX* pVertices;
|
|
|
- // DWORD dwVertex = 0L; // not ref'ed
|
|
|
- DWORD dwNumTriangles = 0L;
|
|
|
- m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
|
|
|
-
|
|
|
- bool bItalic = 0 != ( m_dwFontFlags & D3DFONT_ITALIC ) ;
|
|
|
- FLOAT fBend = 0.0f ;
|
|
|
- if(bItalic)
|
|
|
- fBend = ( ( m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f ) / 4.0f ;
|
|
|
-
|
|
|
- while(c = *strText++) {
|
|
|
- if(c == '\n') {
|
|
|
- x = fStartX;
|
|
|
- y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
|
|
|
- }
|
|
|
- if(c < 32)
|
|
|
- continue;
|
|
|
-
|
|
|
- FLOAT tx1 = m_fTexCoords[c-32][0];
|
|
|
- FLOAT ty1 = m_fTexCoords[c-32][1];
|
|
|
- FLOAT tx2 = m_fTexCoords[c-32][2];
|
|
|
- FLOAT ty2 = m_fTexCoords[c-32][3];
|
|
|
-
|
|
|
- FLOAT w = (tx2-tx1) * m_dwTexWidth / ( 10.0f * m_fTextScale );
|
|
|
- FLOAT h = (ty2-ty1) * m_dwTexHeight / ( 10.0f * m_fTextScale );
|
|
|
-
|
|
|
- if(c != _T(' ')) {
|
|
|
- *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+0,0), D3DXVECTOR3(0,0,-1), tx1, ty2 );
|
|
|
- *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0 + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
|
|
|
- *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
|
|
|
- *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx2, ty1 );
|
|
|
- *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
|
|
|
- *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0 + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
|
|
|
- dwNumTriangles += 2;
|
|
|
-
|
|
|
- if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
|
|
|
- // Unlock, render, and relock the vertex buffer
|
|
|
- m_pVB->Unlock();
|
|
|
- m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
|
|
|
- m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
|
|
|
- dwNumTriangles = 0L;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- x += w;
|
|
|
- }
|
|
|
-
|
|
|
- // Unlock and render the vertex buffer
|
|
|
- m_pVB->Unlock();
|
|
|
- if(dwNumTriangles > 0)
|
|
|
- m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
|
|
|
-
|
|
|
- // Restore the modified renderstates
|
|
|
- m_pd3dDevice->ApplyStateBlock( m_dwSavedStateBlock );
|
|
|
-
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-#endif
|