Пример #1
0
bool CD3DMGEng::DrawText3D ( float x, float y, float z, D3DMATRIX * pMatView, DWORD dwColor, const TCHAR *wszText,  float fTextSize, FONTFLAGS ffFlags, FONTSET fsSet )
{
    D3DSPRITEVERTEX3D * pVertices = NULL;
    D3DXMATRIX          MatWorld, MatView, MatTranslation, MatTransposed;
    DWORD               dwTriangleCount = 0;
    float               fStartX = 0;

    ////////////////////////////////////////////////////
    // Make sure we have a valid vertex buffer.
    if ( m_pVB == NULL )
    {
        return false;
    }

    ////////////////////////////////////////////////////
    // Make sure our texture and coords are loaded.
    if ( m_pFontTexture == NULL || m_bFontInfoLoaded == false )
    {
        return false;
    }

    ///////////////////////////////////////////////////
    // Setup the rendering.
    // Convert our view matrix from D3DMATRIX to D3DXMATRIX
    MatView = *pMatView;
    D3DXMatrixTranspose ( &MatTransposed, &MatView );
    
    // Create an Inverse matrix out of the view matrix (go from view to world space).
    MatTransposed._41 = MatTransposed._42 = 
        MatTransposed._43 = MatTransposed._14 = 
        MatTransposed._24 = MatTransposed._34 = 0.0f;

    // Create an empty identity matrix.
    D3DXMatrixIdentity ( &MatWorld );

    // Add in our scaling here.
    float fSize = fTextSize / 100.0f;
    D3DXMatrixScaling ( &MatWorld, fSize, fSize, fSize );

    // Set position of text in world.
    D3DXMatrixTranslation ( &MatTranslation, x, y, z );

    // Apply settings to new world matrix.
    D3DXMatrixMultiply ( &MatWorld, &MatWorld, &MatTransposed );
    D3DXMatrixMultiply ( &MatWorld, &MatWorld, &MatTranslation );

    m_pDevice->SetFVF ( D3DFVF_SPRITEVERTEX3DTEX );
    m_pDevice->SetStreamSource ( 0, m_pVB, 0, sizeof(D3DSPRITEVERTEX3D) );
    m_pDevice->SetTexture ( 0, m_pFontTexture );
    m_pDevice->SetTransform ( D3DTS_WORLD, &MatWorld );

    x = 0;
    y = 0;

    ///////////////////////////////////////////////////
    // Do flag processing before we go any further.
    if ( ffFlags )
    {
        SIZE sz;

        // First, get extent of drawn text.
        UTIL_GetTextExtent(wszText, &sz, fTextSize);

        // Do math on x coordinate accordingly.
        switch ( ffFlags )
        {
        case D3DFF_CENTERED:
            x -= sz.cx/2;
            break;
        case D3DFF_RIGHT:
            x += sz.cx;
            break;
        case D3DFF_LEFT:
            //x += sz.cx/2;
            break;
        default:
            break;
        }
    } 
        
    
    fStartX = x;
    m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
    while ( *wszText )
    {
        TCHAR c = *wszText++;

        if ( c == _T('\n') )
        {
            x = fStartX;
            y += m_aFontCoords[fsSet].fHeight;
            continue;
        }

        if ( c < _T(' ') || c > _T(128) )
        {
            continue;
        }

        float tx1 = m_aFontCoords[fsSet+c-32].tx1;
        float tx2 = m_aFontCoords[fsSet+c-32].tx2;
        float ty1 = m_aFontCoords[fsSet+c-32].ty1;
        float ty2 = m_aFontCoords[fsSet+c-32].ty2;
        float   w = m_aFontCoords[fsSet+c-32].fWidth;
        float   h = m_aFontCoords[fsSet+c-32].fHeight;

        if ( c == _T(' ') )
        {
            x += w;
            continue;
        }

        // First triangle  (bottom right)
        *pVertices++ = InitFont3DVertex ( x+w, y+h, 0.0f, dwColor, tx2, ty1 ); //bottom right.
        *pVertices++ = InitFont3DVertex ( x+w,   y, 0.0f, dwColor, tx2, ty2 ); //top right.
        *pVertices++ = InitFont3DVertex ( x,   y+h, 0.0f, dwColor, tx1, ty1 ); //bottom left.

        // Second triangle (upper left)
        *pVertices++ = InitFont3DVertex ( x,     y, 0.0f, dwColor, tx1, ty2 ); //top left.
        *pVertices++ = InitFont3DVertex ( x+w,   y, 0.0f, dwColor, tx2, ty2 ); //top right.
        *pVertices++ = InitFont3DVertex ( x,   y+h, 0.0f, dwColor, tx1, ty1 ); //bottom right. 
                                            
        x += w;
        dwTriangleCount += 2;

        ////////////////////////////////////////////////////
        // If we've gone over our limit, draw what we have.
        if ( dwTriangleCount*3 >= D3DSPRITE_NUMVERTS-6 )
        {
            m_pVB->Unlock();
            m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwTriangleCount );
            m_pVB->Lock( 0, 0, (void**)&(pVertices=NULL), D3DLOCK_DISCARD );
            dwTriangleCount = 0L;
        }
    }
    m_pVB->Unlock();


    ////////////////////////////////////////////////////
    // Draw if we have anything.
    if ( dwTriangleCount > 0 )
    {
        m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwTriangleCount );
    }
    return true;
}
Пример #2
0
//-----------------------------------------------------------------------------
// Name: Render3DText()
// Desc: Renders 3D text
//-----------------------------------------------------------------------------
HRESULT CD3DFont::Render3DText( const TCHAR* strText, DWORD dwFlags )
{
    if( m_pd3dDevice == NULL )
        return E_FAIL;

    // Setup renderstate
    m_pStateBlockSaved->Capture();
    m_pStateBlockDrawText->Apply();
    m_pd3dDevice->SetFVF( D3DFVF_FONT3DVERTEX );
    m_pd3dDevice->SetPixelShader( NULL );
    m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(FONT3DVERTEX) );

    // Set filter states
    if( dwFlags & D3DFONT_FILTERED )
    {
        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    }

    // Position for each text element
    FLOAT x = 0.0f;
    FLOAT y = 0.0f;

    // Center the text block at the origin (not the viewport)
    if( dwFlags & D3DFONT_CENTERED_X )
    {
        SIZE sz;
        GetTextExtent( strText, &sz );
        x = -(((FLOAT)sz.cx)/10.0f)/2.0f;
    }
    if( dwFlags & D3DFONT_CENTERED_Y )
    {
        SIZE sz;
        GetTextExtent( strText, &sz );
        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 );

    // Adjust for character spacing
    x -= m_dwSpacing / 10.0f;
    FLOAT fStartX = x;
    TCHAR c;

    // Fill vertex buffer
    FONT3DVERTEX* pVertices;
    DWORD         dwNumTriangles = 0L;
    m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );

    while( (c = *strText++) != 0 )
    {
        if( c == '\n' )
        {
            x = fStartX;
            y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
        }

        if( (c-32) < 0 || (c-32) >= 128-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,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,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,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, (void**)&pVertices, D3DLOCK_DISCARD );
                dwNumTriangles = 0L;
            }
        }

        x += w - (2 * m_dwSpacing) / 10.0f;
    }

    // Unlock and render the vertex buffer
    m_pVB->Unlock();
    if( dwNumTriangles > 0 )
        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );

    // Restore the modified renderstates
    m_pStateBlockSaved->Apply();

    return S_OK;
}
Пример #3
0
//-----------------------------------------------------------------------------
// Name: Render3DText()
// Desc: Renders 3D text
//-----------------------------------------------------------------------------
HRESULT CD3DFont::Render3DText( TCHAR* strText, DWORD dwFlags, float r, float g, float b, float a )
{
    D3DMATERIAL8 mtrl;
    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) );
	m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
	m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );

    D3DUtil_InitMaterial( mtrl, r, g, b, a );
    m_pd3dDevice->SetMaterial(&mtrl);

    // 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;
    DWORD         dwNumTriangles = 0L;
    m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );

    while( c = *strText++ )
    {
        if( c == '\n' )
        {
            x = fStartX;
            y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
        }

        if( c == _T('\01'))
        {
            // 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;

			float g1 = (float)((int)(0xFF&*strText++) / 255.f);
			float b1 = (float)((int)(0xFF&*strText++) / 255.f);
			float r1 = (float)((int)(0xFF&*strText++) / 255.f);
			float a1 = (float)((int)(0xFF&*strText++) / 255.f);
			
			D3DUtil_InitMaterial( mtrl, r1,b1,g1,a1 );/*((float)(*strText++))/255.0f, ((float)(*strText++))/255.0f, 
									//	((float)(*strText++))/255.0f, ((float)(*strText++))/255.0f );*/
			m_pd3dDevice->SetMaterial(&mtrl);
			continue;
        }

        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,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,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,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;
}