⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 font.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 CPP
字号:
#include "HEADERS.H"
#include "FONT.H"

USING NAMESPACE CGE::FONT;
#define MAX_NUM_VERTICES 50*6
//////////////////////////////////////////////////////////////
EnFont::EnFont()
{
	this->m_dyEnFontCache = NULL;
	this->m_dyEnFontVB = NULL;
	this->m_dyEnFontDevice = NULL;
	this->m_dwTexHeight = 0;
	this->m_fTextScale = 1.0f;
	this->m_dwTexWidth = 0;
}

EnFont::~EnFont()
{
}

VOID EnFont::Text2DOut(const TCHAR *strText, LONG sx, LONG sy, DWORD rgbFontColour)
{
    if( m_dyEnFontDevice == NULL )
        return;

    FLOAT fStartX = sx;

    CARD2DVERTEX* PV = NULL;
    DWORD         dwNumTriangles = 0;
    m_dyEnFontVB->Lock( 0, 0, (BYTE**)&PV, D3DLOCK_DISCARD );

    while( *strText )
    {
        TCHAR c = *strText++;

        if( c == _T('\n') )
        {
            sx = fStartX;
            sy += (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
        }
        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(' ') )
        {
            *PV++ = CARD2DVERTEX( D3DXVECTOR3(sx+0-0.5f,sy+h-0.5f,0.9f),1.0f, rgbFontColour, tx1, ty2 );
            *PV++ = CARD2DVERTEX( D3DXVECTOR3(sx+0-0.5f,sy+0-0.5f,0.9f),1.0f, rgbFontColour, tx1, ty1 );
            *PV++ = CARD2DVERTEX( D3DXVECTOR3(sx+w-0.5f,sy+h-0.5f,0.9f),1.0f, rgbFontColour, tx2, ty2 );
            *PV++ = CARD2DVERTEX( D3DXVECTOR3(sx+w-0.5f,sy+0-0.5f,0.9f),1.0f, rgbFontColour, tx2, ty1 );
            *PV++ = CARD2DVERTEX( D3DXVECTOR3(sx+w-0.5f,sy+h-0.5f,0.9f),1.0f, rgbFontColour, tx2, ty2 );
            *PV++ = CARD2DVERTEX( D3DXVECTOR3(sx+0-0.5f,sy+0-0.5f,0.9f),1.0f, rgbFontColour, tx1, ty1 );
            dwNumTriangles += 2;

            if( (dwNumTriangles * 3) > (MAX_NUM_VERTICES - 6) )
            {
                m_dyEnFontVB->Unlock();
                m_dyEnFontDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
                PV = NULL;
                m_dyEnFontVB->Lock( 0, 0, (BYTE**)&PV, D3DLOCK_DISCARD );
                dwNumTriangles = 0L;
            }
        }

        sx += w;
    }

    m_dyEnFontVB->Unlock();
    if( dwNumTriangles > 0 )
        m_dyEnFontDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );

}

CardFont::CardFont()
{
	m_pD3DDevice = NULL;
	m_CardFontMap = NULL;
	m_Buffer = NULL;
	m_strFileName = NULL;
	m_sx = m_sy = 0;
	m_CardWidth = 0;
	m_CardHeight = 0;
	m_Align = 0;
	m_CardBufferPtr = 0;
	m_CardMapWidth = 0;
	m_CardMapHeight = 0;
	m_CardOffsetSX = 0;
	m_CardOffsetSY = 0;
	m_CardNumberToRender = 0;
}

CardFont::~CardFont()
{
	SAFE_RELEASE(m_pD3DDevice);
	SAFE_RELEASE(m_CardFontMap);
	SAFE_RELEASE(m_Buffer);
	SAFE_DELETE_ARRAY(m_strFileName);
}

BOOL CardFont::CreateCardFont(LPDIRECT3DDEVICE8 device,DWORD clrKey)
{
	HRESULT hr;	
	if ( device == NULL )
		return FALSE;
	
	m_pD3DDevice = device;
	
	hr = D3DXCreateTextureFromFileEx(device, m_strFileName, 
		D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_A1R5G5B5, 
		D3DPOOL_DEFAULT, D3DX_FILTER_TRIANGLE, D3DX_FILTER_TRIANGLE,
		clrKey, NULL, NULL, &m_CardFontMap);
	
	if ( FAILED(hr) )
		return FALSE;
	hr = device->CreateVertexBuffer( FONT_NUM_IN_LINE * 6 * sizeof(FONT::CARD2DVERTEX),
		0,0,D3DPOOL_MANAGED,&m_Buffer);
	if ( FAILED(hr) )
		return FALSE;
	return TRUE;
}

VOID CardFont::SetfreeContext()
{
	SAFE_RELEASE(m_pD3DDevice);
	SAFE_RELEASE(m_CardFontMap);
	SAFE_RELEASE(m_Buffer);
}


VOID CardFont::SetOut2DCard(LONG sx, LONG sy, LONG cx,LONG cy,UINT nAlign)
{
	m_sx = sx;m_sy = sy;
	m_Align = nAlign;
	m_CardWidth = cx; m_CardHeight = cy;
}

VOID CardFont::Out2DCard(LONG x, LONG y,FLOAT fSize,DWORD clr)
{
	D3DXVECTOR3 billboardx = D3DXVECTOR3(1,0,0);
	D3DXVECTOR3 billboardy = D3DXVECTOR3(0,1,0);


	FLOAT TU = (FLOAT)(x * m_CardWidth + m_CardOffsetSX) / m_CardMapWidth;
	FLOAT TV = (FLOAT)(y * m_CardHeight + m_CardOffsetSY) / m_CardMapHeight;
	FLOAT TDU = (FLOAT)m_CardWidth / (m_CardMapWidth);
	FLOAT TDV = (FLOAT)m_CardHeight / (m_CardMapHeight);


	D3DXVECTOR3 coords(m_sx,m_sy,0.9f);
	coords = coords - billboardx * (0.5f * fSize)
					+ billboardy * (0.5f * fSize);
	*m_CardBufferPtr = CARD2DVERTEX(coords,1.0f,clr,TU,TV+TDV);m_CardBufferPtr++;
	coords = coords + billboardx * fSize;
	*m_CardBufferPtr = CARD2DVERTEX(coords,1.0f,clr,TU+TDU,TV+TDV);m_CardBufferPtr++;
	coords = coords - billboardx * fSize
					- billboardy * fSize;
	*m_CardBufferPtr = CARD2DVERTEX(coords,1.0f,clr,TU,TV);m_CardBufferPtr++;

	*m_CardBufferPtr = CARD2DVERTEX(coords,1.0f,clr,TU,TV);m_CardBufferPtr++;

	coords = coords + billboardx * fSize
					+ billboardy * fSize;
	*m_CardBufferPtr = CARD2DVERTEX(coords,1.0f,clr,TU+TDU,TV+TDV);m_CardBufferPtr++;

	coords = coords - billboardy * fSize;
	*m_CardBufferPtr = CARD2DVERTEX(coords,1.0f,clr,TU+TDU,TV);m_CardBufferPtr++;

	if ( m_Align == ALIGN_ACROSS )
		m_sx += fSize;
	else
		m_sy += fSize;
	m_CardNumberToRender++;
	CHECK_RANGE(m_CardNumberToRender,0,FONT_NUM_IN_LINE);
}

VOID CardFont::SetCardFile(TCHAR *strFileName,LONG wsize,LONG hsize)
{
	if ( strFileName != NULL)
	{
		SAFE_DELETE_ARRAY(m_strFileName);
		m_strFileName = new TCHAR[_tcslen(strFileName)+1];
		_tcscpy(m_strFileName,strFileName);
		m_CardMapWidth = wsize;
		m_CardMapHeight = hsize;
	}
}

BOOL CardFont::LockCardBuffer()
{
	HRESULT hr;
	hr = m_Buffer->Lock( 0,0,(BYTE**)&m_CardBufferPtr,0);
	if(FAILED(hr))
		return FALSE;
	return TRUE;
}

VOID CardFont::UnlockCardBuffer()
{
	m_Buffer->Unlock();
}

VOID CardFont::CardInScene()
{
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE ,TRUE);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF ,0x08);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE,TRUE);
	m_pD3DDevice->SetTexture(0,m_CardFontMap);
	m_pD3DDevice->SetStreamSource(0,m_Buffer,sizeof(FONT::CARD2DVERTEX));
	m_pD3DDevice->SetVertexShader(CARD2DVERTEX::FVF_CARD2DVERTEX);
	m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,m_CardNumberToRender * 2);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE,FALSE);
	m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE ,FALSE);
	m_pD3DDevice->SetTexture(0,0);
}

VOID CardFont::SetCardOffSet(LONG sx, LONG sy)
{
	m_CardOffsetSX = sx;
	m_CardOffsetSY = sy;
}

VOID EnFont::SetfreeContext()
{
	SAFE_RELEASE(m_dyEnFontVB);
    m_dwSavedStateBlock    = 0L;
    m_dwDrawTextStateBlock = 0L;
}

BOOL EnFont::SetEnFont(LPDIRECT3DDEVICE8 device,TCHAR *strFontface, LONG dwFontHeight, LONG dwBold, BOOL bItalic, BOOL bUnderline)
{
	HRESULT hr;
	if (device == NULL) return FALSE;
	m_dyEnFontDevice = device;

    m_fTextScale  = 1.0f;
	
	m_dwFontHeight = dwFontHeight;

    if( m_dwFontHeight > 40 )
        m_dwTexWidth = m_dwTexHeight = 1024;
    else if( m_dwFontHeight > 20 )
        m_dwTexWidth = m_dwTexHeight = 512;
    else
        m_dwTexWidth  = m_dwTexHeight = 256;
	
    D3DCAPS8 d3dCaps;
    m_dyEnFontDevice->GetDeviceCaps( &d3dCaps );
	
    if( m_dwTexWidth > d3dCaps.MaxTextureWidth )
    {
        m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwTexWidth;
        m_dwTexWidth = m_dwTexHeight = d3dCaps.MaxTextureWidth;
    }
	
    hr = m_dyEnFontDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
		0, D3DFMT_A4R4G4B4,
		D3DPOOL_MANAGED, &m_dyEnFontCache );
    if( FAILED(hr) )
        return FALSE;


    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;

    HDC hDC = CreateCompatibleDC( NULL );
	DWORD* dyEnBitMaps = NULL;
    HBITMAP hBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
		(VOID**)&dyEnBitMaps, NULL, 0 );
    SetMapMode( hDC, MM_TEXT );
	
    LONG nHeight = -MulDiv( m_dwFontHeight, 
        (LONG)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
    HFONT hEnFont    = CreateFont( nHeight, 0, 0, 0, dwBold, bItalic,
		bUnderline, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
		VARIABLE_PITCH, strFontface );
    if( NULL == hEnFont )
    {
		DeleteObject(hBitmap);
		DeleteDC(hDC);
		return FALSE;
	}
	
    SelectObject( hDC, hBitmap );
    SelectObject( hDC, hEnFont );
	
    SetTextColor( hDC, RGB(255,255,255) );
    SetBkColor(   hDC, 0x00000000 );
    SetTextAlign( hDC, TA_TOP );

    DWORD x = 0;
    DWORD y = 0;
    TCHAR str[2] = _T("x");
    SIZE size;
	
    for( TCHAR 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;
        }
		
        ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );
		
        m_fTexCoords[c-32][0] = ((FLOAT)(x+0))/m_dwTexWidth;
        m_fTexCoords[c-32][1] = ((FLOAT)(y+0))/m_dwTexHeight;
        m_fTexCoords[c-32][2] = ((FLOAT)(x+0+size.cx))/m_dwTexWidth;
        m_fTexCoords[c-32][3] = ((FLOAT)(y+0+size.cy))/m_dwTexHeight;
		
        x += size.cx+1;
    }
	
    D3DLOCKED_RECT d3dlr;
    m_dyEnFontCache->LockRect( 0, &d3dlr, 0, 0 );
    BYTE* pDstRow = (BYTE*)d3dlr.pBits;
    WORD* pDst16;
    BYTE bAlpha;
	
    for( y=0; y < m_dwTexHeight; y++ )
    {
        pDst16 = (WORD*)pDstRow;
        for( x=0; x < m_dwTexWidth; x++ )
        {
            bAlpha = (BYTE)((dyEnBitMaps[m_dwTexWidth*y + x] & 0xff) >> 4);
            if (bAlpha > 0)
            {
                *pDst16++ = (bAlpha << 12) | 0x0fff;
            }
            else
            {
                *pDst16++ = 0x0000;
            }
        }
        pDstRow += d3dlr.Pitch;
    }
	
    m_dyEnFontCache->UnlockRect(0);
    DeleteObject( hBitmap );
    DeleteDC( hDC );
    DeleteObject( hEnFont );
	return TRUE;
	
}

VOID EnFont::BeginTextOut()
{
	m_dyEnFontDevice->CaptureStateBlock( m_dwSavedStateBlock );
    m_dyEnFontDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
    m_dyEnFontDevice->SetVertexShader( CARD2DVERTEX::FVF_CARD2DVERTEX );
    m_dyEnFontDevice->SetPixelShader( NULL );
    m_dyEnFontDevice->SetStreamSource( 0, m_dyEnFontVB, sizeof(CARD2DVERTEX) );	
}

VOID EnFont::EndTextOut()
{
    m_dyEnFontDevice->ApplyStateBlock( m_dwSavedStateBlock );
}

BOOL EnFont::CreateContext(LPDIRECT3DDEVICE8 device)
{
	HRESULT hr;
	hr = m_dyEnFontDevice->CreateVertexBuffer( MAX_NUM_VERTICES * sizeof(CARD2DVERTEX),
		D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
		D3DPOOL_DEFAULT, &m_dyEnFontVB );
	if(FAILED(hr))	return FALSE;
	// 创建2块
    for( UINT which=0; which<2; which++ )
    {
        m_dyEnFontDevice->BeginStateBlock();
        m_dyEnFontDevice->SetTexture( 0, m_dyEnFontCache );
		m_dyEnFontDevice->SetRenderState( D3DRS_ZENABLE,FALSE);
		m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
		m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
		m_dyEnFontDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
        m_dyEnFontDevice->SetRenderState( D3DRS_SRCBLEND,   D3DBLEND_SRCALPHA );
        m_dyEnFontDevice->SetRenderState( D3DRS_DESTBLEND,  D3DBLEND_INVSRCALPHA );
        m_dyEnFontDevice->SetRenderState( D3DRS_ALPHATESTENABLE,  TRUE );
        m_dyEnFontDevice->SetRenderState( D3DRS_ALPHAREF,         0x08 );
        m_dyEnFontDevice->SetRenderState( D3DRS_ALPHAFUNC,  D3DCMP_GREATEREQUAL );
        m_dyEnFontDevice->SetRenderState( D3DRS_FILLMODE,   D3DFILL_SOLID );
        m_dyEnFontDevice->SetRenderState( D3DRS_CULLMODE,   D3DCULL_CCW );
        m_dyEnFontDevice->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
        m_dyEnFontDevice->SetRenderState( D3DRS_CLIPPING,         TRUE );
        m_dyEnFontDevice->SetRenderState( D3DRS_EDGEANTIALIAS,    FALSE );
        m_dyEnFontDevice->SetRenderState( D3DRS_CLIPPLANEENABLE,  FALSE );
        m_dyEnFontDevice->SetRenderState( D3DRS_VERTEXBLEND,      FALSE );
        m_dyEnFontDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
        m_dyEnFontDevice->SetRenderState( D3DRS_FOGENABLE,        FALSE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_POINT );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
        m_dyEnFontDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
        m_dyEnFontDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
        m_dyEnFontDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

        if( which==0 )
            m_dyEnFontDevice->EndStateBlock( &m_dwSavedStateBlock );
        else
            m_dyEnFontDevice->EndStateBlock( &m_dwDrawTextStateBlock );
    }

	return TRUE;
}

VOID CardFont::BeginCardOut()
{

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -