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

📄 cdxapp.cpp

📁 一个Direct3DRM的包装类的例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    return( TRUE );
}

#ifdef _DEBUG

static void StatsHelper( char *szBuff,int nLen,LPDIRECTDRAWSURFACE lpSurf, SIZE *pSize )
{
    /*  Helper function  */

    HDC         hDC;
    HFONT       hOldFont;
    HRESULT     err;
    RECT        r;

    if ( (err=lpSurf->GetDC(&hDC))!=DD_OK )
    {
        pApp->ErrHandler( "StatsHelper() Failure to GetDC for surface ",szBuff,err );
        return;
    }

    /*  Render info to surface using GDI  */

    hOldFont = (HFONT)::SelectObject( hDC,gStats.hFont );
    ::SetTextColor( hDC,RGB(255,255,255) );
    ::SetBkColor( hDC,RGB(0,0,0) );
    ::SetBkMode( hDC,OPAQUE );
    ::GetTextExtentPoint32( hDC,szBuff,nLen,pSize );
    ::SetRect( &r,0,0,pSize->cx,pSize->cy );
    ::ExtTextOut( hDC,0,0,ETO_OPAQUE,&r,szBuff,nLen,NULL );
    ::SelectObject( hDC,hOldFont );

    /*  Release GDI interface  */

    lpSurf->ReleaseDC( hDC );
}

BOOL CDXApp::ShowStatistics()
{
    /*  Update surface with some stats  */

    float                   fps=GetFPS();
    DWORD                   dwPolys=GetTPS();
    char                    szBuff[128];
    int                     nLen;
    LPDIRECTDRAWSURFACE     lpSurf=GetStatsSurface();

    if ( !lpSurf ) return( TRUE );

    nLen = wsprintf( szBuff,"%d.%02d fps, %lu tps",(((int)fps)*100)/100,(((int)fps)*100)%100,dwPolys );

    StatsHelper( szBuff,nLen,lpSurf,&gStats.sizeStats );

    return( TRUE );
}

BOOL CDXApp::ShowModeInfo()
{
    /*  Update the info surface with some stats  */

    HRESULT                 err;
    char                    szBuff[128];
    int                     nLen;
    LPDIRECTDRAWSURFACE     lpSurf=GetInfoSurface();

    if ( !lpSurf ) return( TRUE );

    nLen = wsprintf( szBuff,"%dx%dx%d (%s)",m_sizeScreen.cx,m_sizeScreen.cy,GetBitDepth(),(IsRGB()?"RGB":"MONO"    ) );

    StatsHelper( szBuff,nLen,lpSurf,&gStats.sizeInfo );

    return( TRUE );
}

BOOL CDXApp::InitialiseStatistics()
{
    /*  Create our surfaces for stats info, etc  */

    DDCOLORKEY          ddck;
    DDSURFACEDESC       ddsd;
    HRESULT             err;
    BOOL                bError=FALSE;

    /*  Cater for bogus recalling  */

    RELEASE( m_pStatsSurface );
    RELEASE( m_pInfoSurface );

    if ( gStats.hFont!=NULL )
    {
        ::DeleteObject( gStats.hFont );
        gStats.hFont=NULL;
    }

    gStats.bValid = FALSE;

    /*  Create the GDI font  */

    gStats.hFont = ::CreateFont(12,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,0,0,0,VARIABLE_PITCH,"Arial");

    /*  Create the surfaces  */

    ZeroMemory( &ddsd,sizeof(ddsd) );
    ddsd.dwSize         = sizeof(ddsd);
    ddsd.dwFlags        = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    ddsd.dwHeight       = 50;       /*  50 should be plenty  */
    ddsd.dwWidth        = 300;      /*  300 should be plenty too  */
    if ( (err=m_pDD->CreateSurface(&ddsd,&m_pStatsSurface,NULL))!=DD_OK )
    {
        ErrHandler( "CDXApp::InitialiseStats()","Error creating stats surface",err );
        bError=TRUE;
    }
    else
    {
        ZeroMemory( &ddck,sizeof(ddck) );
        m_pStatsSurface->SetColorKey( DDCKEY_SRCBLT,&ddck );

        if ( (err=m_pDD->CreateSurface(&ddsd,&m_pInfoSurface,NULL))!=DD_OK )
        {
            ErrHandler( "CDXApp::InitialiseStats()","Error creating info surface",err );
            bError=TRUE;
        }
        else
        {
            ZeroMemory( &ddck,sizeof(ddck) );
            m_pInfoSurface->SetColorKey( DDCKEY_SRCBLT,&ddck );
        }
    }

    if ( bError )
    {
        RELEASE( m_pStatsSurface );
        RELEASE( m_pInfoSurface );
        if ( gStats.hFont!=NULL )
        {
            ::DeleteObject( gStats.hFont );
            gStats.hFont=NULL;
        }
        return( FALSE );
    }

    return( TRUE );
}

float CDXApp::GetFPS()
{
    /*  Calculate the frame rate  */

    return( gStats.floatFPS );
}

DWORD CDXApp::GetTPS()
{
    /*  Determine the triangles being drawn per second (ave)  */

    return( gStats.dwTPS );
}

void CDXApp::CalculateFrameRate()
{
    /*  Calculate frames per second, etc, at some interval  */

    gStats.dwFrameCount++;
    if ( ++gStats.dwIntervalCount >= FRAME_INTERVAL )
    {
        double      t;
        int         p, f;
        time_t      time=clock();

        gStats.dwIntervalCount = 0;
        t               = (time-gStats.timeLast)/(double)CLOCKS_PER_SEC;
        gStats.timeLast = time;

        p               = Get3DDevice()->GetTrianglesDrawn() - gStats.dwLastTriangles;
        gStats.dwLastTriangles = Get3DDevice()->GetTrianglesDrawn();

        f               = gStats.dwFrameCount;
        gStats.dwFrameCount = 0;

        gStats.floatFPS = (float) (f/t);
        gStats.dwTPS    = (DWORD) (p/t);

        ShowStatistics();
        ShowModeInfo();

        gStats.bValid   = TRUE;
    }
}

void CDXApp::DisplayStats()
{
    /*  Update the info surfaces and blt them to render target  */

    LPDIRECT3DDEVICE2       lpD3D2=NULL;
    LPDIRECTDRAWSURFACE     lpTarget=NULL;
    HRESULT                 err;
    RECT                    rc;

    /*  Show the frame rate centered across the top of the window  */

    CalculateFrameRate();

    /*  Don't bother if not initialised yet  */

    if ( !gStats.bValid ) return;

    if ( (err=Get3DDevice()->GetDirect3DDevice2(&lpD3D2))!=D3DRM_OK )
    {
        ErrHandler( "CDXApp::DisplayStats()","GetDirect3DDevice2 Failed",err );
        return;
    }

    if ( (err=lpD3D2->GetRenderTarget(&lpTarget))!=DD_OK )
    {
        ErrHandler( "CDXApp::DisplayStats()","GetRenderTarget Failed",err );
        RELEASE( lpD3D2 );
        return;
    }

    if ( gStats.sizeStats.cx < m_sizeScreen.cx && gStats.sizeStats.cy < m_sizeScreen.cy )
    {
        int     xdif=(m_sizeScreen.cx-gStats.sizeStats.cx)/2;

        ::SetRect( &rc,0,0,gStats.sizeStats.cx,gStats.sizeStats.cy );
        if ( GetStatsSurface()!=NULL )
        {
            if ( (err=lpTarget->BltFast(xdif,0,GetStatsSurface(),&rc,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT))!=DD_OK )
            {
                /*  Not an important error  */

                if ( lpTarget->IsLost() ) lpTarget->Restore();
                if ( GetStatsSurface()->IsLost() ) GetStatsSurface()->Restore();
            }
            else
            {
                /*  Add rectangle as dirty  */

                GetViewport()->ForceUpdate( xdif,0,gStats.sizeStats.cx+xdif,gStats.sizeStats.cy );
            }
        }
    }

    /*  Show the info centered across the bottom of the window  */

    if ( gStats.sizeInfo.cx < m_sizeScreen.cx && gStats.sizeInfo.cy < m_sizeScreen.cy )
    {
        int     xdif=(m_sizeScreen.cx-gStats.sizeInfo.cx)/2;
        int     ydif=m_sizeScreen.cy-gStats.sizeInfo.cy;

        ::SetRect( &rc,0,0,gStats.sizeInfo.cx,gStats.sizeInfo.cy );
        if ( GetInfoSurface()!=NULL )
        {
            if ( (err=lpTarget->BltFast(xdif,ydif,GetInfoSurface(),&rc,DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT))!=DD_OK )
            {
                /*  Not an important error  */

                if ( lpTarget->IsLost() ) lpTarget->Restore();
                if ( GetInfoSurface()->IsLost() ) GetInfoSurface()->Restore();
            }
            else
            {
                /*  Add dirty rectange  */

                GetViewport()->ForceUpdate( xdif,ydif,gStats.sizeInfo.cx+xdif,ydif+gStats.sizeInfo.cy );
            }
        }
    }

    RELEASE( lpTarget );
    RELEASE( lpD3D2 );
}

#endif      // _DEBUG


BOOL CDXApp::IsRGB()
{
    return( !bMono );
}

BOOL CDXApp::ActivateMenu()
{
    /*  Invoke the menu (only) if full screen mode  */

    if ( GetHMenu()==NULL ) return( FALSE );

    if ( !IsFullScreen() ) return( TRUE );

    ::SetMenu( GetHWnd(),GetHMenu() );      /*  This will also force redraw  */

    PauseApp( TRUE );

    return( TRUE );
}

void CDXApp::PauseApp( BOOL bPause )
{
    /*  Pause or un-pause the application  */

    HRESULT                 err;
    HDC                     hDC;

    if ( bPause!=m_bIsPaused )
    {
        m_bIsPaused = bPause;

        if ( m_bIsPaused )
        {
            /*  Need to display a paused message on screen  */

            if ( IsFullScreen() )
            {
                if ( (err=m_pDD2->FlipToGDISurface())!=DD_OK )
                {
                    ErrHandler( "CDXApp::PauseApp()","FlipToGDISurface Failed",err );
                    return;
                }
            }

            /*  Use simple GDI  */

            if ( IsFullScreen() ) err=m_pPrimarySurface->GetDC(&hDC); else
            {
                hDC = ::GetDC( GetHWnd() );
                err = DD_OK;
            }

            if ( err==DD_OK )
            {
                RECT        rc;
                LPCSTR      lpszMsg="Paused";

                ::SetRect( &rc,0,0,m_sizeScreen.cx,m_sizeScreen.cy );
                ::SetBkMode( hDC,TRANSPARENT );
                ::SetTextColor( hDC,RGB(255,255,255) );
                ::DrawText( hDC,lpszMsg,lstrlen(lpszMsg),&rc,DT_CENTER|DT_VCENTER|DT_SINGLELINE );

                if ( !IsFullScreen() )
                {
                    ::ReleaseDC( GetHWnd(),hDC );
                }
                else
                {
                    if ( (err=m_pPrimarySurface->ReleaseDC(hDC))!=DD_OK )
                    {
                        ErrHandler( "CDXApp::PauseApp()","ReleaseDC Failed",err );
                    }
                }
            }
            else
            {
                ErrHandler( "CDXApp::PauseApp()","GetDC Failed",err );
            }
        }
        else
        {
            /*  Force update of entire viewport  */

            m_bForceFullUpdate = TRUE;

            /*  Remove any menu for full screen mode  */

            if ( IsFullScreen() && GetHMenu()!=NULL ) ::SetMenu( GetHWnd(),NULL );
        }
    }
}

⌨️ 快捷键说明

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