home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / tri3 / stats.cpp < prev    next >
C/C++ Source or Header  |  1997-07-14  |  9KB  |  312 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: stats.cpp
  6.  *
  7.  ***************************************************************************/
  8. #include "d3dmain.h"
  9.  
  10. /*
  11.  * GLOBAL VARIABLES
  12.  */
  13. extern D3DAppInfo* d3dapp;        /* Pointer to read only collection of DD and D3D
  14.                    objects maintained by D3DApp */
  15. extern d3dmainglobals myglobs;        /* collection of global variables */
  16.  
  17. static struct {
  18.     HFONT hFont;
  19.     SIZE szFrameRate;
  20.     SIZE szInfo;
  21. } statglobs;
  22.  
  23.  /************************************************************************
  24.   Frame rate and info text
  25.  ************************************************************************/
  26.  
  27. BOOL
  28. WriteFrameRateBuffer(float fps, long tps)
  29. {
  30.     HRESULT LastError;
  31.     HDC hdc;
  32.     RECT rc;
  33.     char buf1[30], buf2[30], buf[60];
  34.     int len;
  35.  
  36.     if (!myglobs.lpFrameRateBuffer)
  37.     return TRUE;
  38.     if (fps > 0.0f)
  39.         wsprintf(buf1, "%d.%02d fps   ",
  40.                     (int)( fps * 100 ) / 100,
  41.                     (int)( fps * 100 ) % 100);
  42.     else
  43.         buf1[0] = 0;
  44.     if (tps > 0)
  45.         wsprintf(buf2, "%ld tps   ", tps);
  46.     else
  47.         buf2[0] = 0;
  48.     len = wsprintf(buf, "%s%s", buf1, buf2);
  49.     if (!myglobs.lpFrameRateBuffer)
  50.         return FALSE;
  51.     LastError = myglobs.lpFrameRateBuffer->GetDC(&hdc);
  52.     if (LastError != DD_OK) {
  53.     /*
  54.      * If this fails, it's not vital, so don't report an error.
  55.      */
  56.     return TRUE;
  57.     }
  58.     SelectObject(hdc, statglobs.hFont);
  59.     SetTextColor(hdc, RGB(255,255,0));
  60.     SetBkColor(hdc, RGB(0,0,0));
  61.     SetBkMode(hdc, OPAQUE);
  62.     GetTextExtentPoint32(hdc, buf, len, &statglobs.szFrameRate);
  63.     SetRect(&rc, 0, 0, statglobs.szFrameRate.cx, statglobs.szFrameRate.cy);
  64.     ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, buf, len, NULL);
  65.     myglobs.lpFrameRateBuffer->ReleaseDC(hdc);
  66.     return TRUE;
  67. }
  68.  
  69. BOOL
  70. WriteInfoBuffer(void)
  71. {
  72.     HRESULT LastError;
  73.     HDC hdc;
  74.     RECT rc;
  75.     char buf[40];
  76.     int len;
  77.  
  78.     if (!myglobs.lpInfoBuffer)
  79.     return TRUE;
  80.     if (d3dapp->bFullscreen)
  81.     len = wsprintf(buf, "%dx%dx%d (%s)", d3dapp->ThisMode.w, d3dapp->ThisMode.h, d3dapp->ThisMode.bpp,
  82.                (d3dapp->ThisDriver.Desc.dcmColorModel == D3DCOLOR_MONO) ? "MONO" : "RGB");
  83.     else
  84.     len = wsprintf(buf, "%dx%d (%s)", d3dapp->szClient.cx, d3dapp->szClient.cy, 
  85.                (d3dapp->ThisDriver.Desc.dcmColorModel == D3DCOLOR_MONO) ? "MONO" : "RGB");
  86.     if (!myglobs.lpInfoBuffer)
  87.         return FALSE;
  88.     LastError = myglobs.lpInfoBuffer->GetDC(&hdc);
  89.     if (LastError != DD_OK) {
  90.     /*
  91.      * If this fails, it's not vital, so don't report an error.
  92.      */
  93.     return TRUE;
  94.     }
  95.  
  96.     SelectObject(hdc, statglobs.hFont);
  97.     SetTextColor(hdc, RGB(255,255,0));
  98.     SetBkColor(hdc, RGB(0,0,0));
  99.     SetBkMode(hdc, OPAQUE);
  100.     GetTextExtentPoint32(hdc, buf, len, &statglobs.szInfo);
  101.     SetRect(&rc, 0, 0, statglobs.szInfo.cx, statglobs.szInfo.cy);
  102.     ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, buf, len, NULL);
  103.     myglobs.lpInfoBuffer->ReleaseDC(hdc);
  104.     return TRUE;
  105. }
  106.  
  107. void
  108. ReleaseFontAndTextBuffers(void)
  109. {
  110.     RELEASE(myglobs.lpInfoBuffer);
  111.     RELEASE(myglobs.lpFrameRateBuffer);
  112.     if (statglobs.hFont != NULL) {
  113.         DeleteObject(statglobs.hFont);
  114.     statglobs.hFont = NULL;
  115.     }
  116. }
  117.  
  118. BOOL
  119. InitFontAndTextBuffers(void)
  120. {
  121.     DDCOLORKEY          ddck;
  122.     DDSURFACEDESC       ddsd;
  123.     HDC hdc;
  124.     HRESULT ddrval;
  125.     char dummyinfo[] = "000x000x00 (MONO) 0000";
  126.     char dummyfps[] = "000.00 fps 00000000.00 tps 0000.00 mppps";
  127.    
  128.     /*
  129.      * Create the font.
  130.      */
  131.     RELEASE(myglobs.lpInfoBuffer);
  132.     RELEASE(myglobs.lpFrameRateBuffer);
  133.     if (statglobs.hFont != NULL) {
  134.         DeleteObject(statglobs.hFont);
  135.     statglobs.hFont = NULL;
  136.     }
  137.     statglobs.hFont = CreateFont(
  138.         d3dapp->szClient.cx <= 600 ? 12 : 24,
  139.         0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
  140.         ANSI_CHARSET,
  141.         OUT_DEFAULT_PRECIS,
  142.         CLIP_DEFAULT_PRECIS,
  143.         DEFAULT_QUALITY,
  144.         VARIABLE_PITCH,
  145.         "Arial" );
  146.  
  147.     hdc = GetDC(NULL);
  148.     SelectObject(hdc, statglobs.hFont);
  149.     GetTextExtentPoint(hdc, dummyfps, strlen(dummyfps), &statglobs.szFrameRate);
  150.     GetTextExtentPoint(hdc, dummyinfo, strlen(dummyinfo), &statglobs.szInfo);
  151.     ReleaseDC(NULL, hdc);
  152.  
  153.     memset( &ddsd, 0, sizeof( ddsd ) );
  154.     ddsd.dwSize = sizeof( ddsd );
  155.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
  156.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  157.     ddsd.dwHeight = statglobs.szFrameRate.cy;
  158.     ddsd.dwWidth = statglobs.szFrameRate.cx;
  159.     ddrval = D3DAppCreateSurface(&ddsd, &myglobs.lpFrameRateBuffer);
  160.     if (ddrval != DD_OK) {
  161.     Msg("Could not create frame rate buffer.\n%s", D3DAppErrorToString(ddrval));    
  162.         goto exit_with_error;
  163.     }
  164.     memset(&ddck, 0, sizeof(ddck));
  165.     myglobs.lpFrameRateBuffer->SetColorKey(DDCKEY_SRCBLT, &ddck);
  166.     if (!WriteFrameRateBuffer(0.0f, 0)) {
  167.         goto exit_with_error;
  168.     }
  169.     memset( &ddsd, 0, sizeof( ddsd ) );
  170.     ddsd.dwSize = sizeof( ddsd );
  171.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
  172.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  173.     ddsd.dwHeight = statglobs.szInfo.cy;
  174.     ddsd.dwWidth = statglobs.szInfo.cx;
  175.     ddrval = D3DAppCreateSurface(&ddsd, &myglobs.lpInfoBuffer);
  176.     if (ddrval != DD_OK) {
  177.     Msg("Could not create info buffer.\n%s", D3DAppErrorToString(ddrval));
  178.     goto exit_with_error;
  179.     }
  180.     memset(&ddck, 0, sizeof(ddck));
  181.     myglobs.lpInfoBuffer->SetColorKey(DDCKEY_SRCBLT, &ddck);
  182.     if (!WriteInfoBuffer())
  183.     goto exit_with_error;
  184.     return TRUE;
  185. exit_with_error:
  186.     RELEASE(myglobs.lpInfoBuffer);
  187.     RELEASE(myglobs.lpFrameRateBuffer);
  188.     if (statglobs.hFont != NULL) {
  189.         DeleteObject(statglobs.hFont);
  190.     }
  191.     return FALSE;
  192. }
  193.  
  194. /*************************************************************************
  195.   Frame rate output.
  196.  *************************************************************************/
  197.  
  198. #define INTERVAL 100
  199.  
  200. char StatTxt[100];
  201. int StatTxtLen;
  202. int count = 0;
  203. int last_polygons = 0;
  204. int this_frames = 0;
  205. time_t last_time;
  206. float fps;
  207. long tps;
  208.  
  209. /*
  210.  * ResetFrameRate
  211.  * Initializes the frame rate counter.
  212.  */
  213. void
  214. ResetFrameRate(void)
  215. {
  216.     last_time = clock();
  217.     count = 0;
  218.     last_polygons = 0;
  219.     this_frames = 0;
  220.     fps = 0.0f; tps = 0;
  221.     StatTxt[0] = 0;
  222.     StatTxtLen = 0;
  223. }
  224.  
  225. BOOL
  226. CalculateFrameRate(void)
  227. {
  228.     /*
  229.      * Calculate the frame rate and get other stats.
  230.      */
  231.     count++;
  232.     this_frames++;
  233.     if (count == INTERVAL) {
  234.         double t;
  235.     int p, f;
  236.     D3DSTATS stats;
  237.         time_t this_time;
  238.  
  239.         count = 0;
  240.     this_time = clock();
  241.     t = (this_time - last_time) / (double)CLOCKS_PER_SEC;
  242.     last_time = this_time;
  243.  
  244.         memset(&stats, 0, sizeof(D3DSTATS));
  245.         stats.dwSize = sizeof(D3DSTATS);
  246.         d3dapp->lpD3DDevice->GetStats(&stats);
  247.     p = stats.dwTrianglesDrawn - last_polygons;
  248.     last_polygons = stats.dwTrianglesDrawn;
  249.  
  250.     f = this_frames;
  251.     this_frames = 0;
  252.  
  253.         fps = (float)(f / t);
  254.         tps = (long)(p / t);
  255.  
  256.         if (myglobs.bShowFrameRate) {
  257.             if (!WriteFrameRateBuffer(fps, tps))
  258.                 return FALSE;            
  259.         }
  260.     }
  261.     return TRUE;
  262. }
  263.  
  264. /*
  265.  * DisplayFrameRate
  266.  * Outputs frame rate info and screen mode to back buffer when appropriate.
  267.  */
  268. BOOL
  269. DisplayFrameRate(int* count, LPD3DRECT lpExtents )
  270. {
  271.     RECT rc;
  272.     int x, y;
  273.     HRESULT ddrval = DD_OK;
  274.     if (myglobs.bShowFrameRate && !myglobs.bSingleStepMode && statglobs.szFrameRate.cx > 0 && statglobs.szFrameRate.cy > 0 &&
  275.         statglobs.szFrameRate.cx < d3dapp->szClient.cx && statglobs.szFrameRate.cy < d3dapp->szClient.cy) {
  276.         SetRect(&rc, 0, 0, statglobs.szFrameRate.cx, statglobs.szFrameRate.cy);
  277.         x = (int)(0.5 * (d3dapp->szClient.cx - statglobs.szFrameRate.cx) + 0.5);
  278.         y = 0;
  279.     if (myglobs.lpFrameRateBuffer)
  280.         ddrval = d3dapp->lpBackBuffer->BltFast(x, y, myglobs.lpFrameRateBuffer, &rc,
  281.                          DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
  282.     if (ddrval != DD_OK) {
  283.         /*
  284.          * Blting the frame rate has failed. Since it is not vital, we
  285.          * aren't going to report an error.
  286.          */
  287.         return TRUE;
  288.     }
  289.     SetRect((LPRECT)(lpExtents), x, y, statglobs.szFrameRate.cx + x, statglobs.szFrameRate.cy);
  290.     ++(*count);
  291.     ++lpExtents;
  292.     }
  293.     if (myglobs.bShowInfo && statglobs.szInfo.cx < d3dapp->szClient.cx && statglobs.szInfo.cy < d3dapp->szClient.cy) {
  294.         SetRect(&rc, 0, 0, statglobs.szInfo.cx, statglobs.szInfo.cy);
  295.         x = (int)(0.5 * (d3dapp->szClient.cx - statglobs.szInfo.cx) + 0.5);
  296.         y = d3dapp->szClient.cy - statglobs.szInfo.cy;
  297.     if (myglobs.lpInfoBuffer)
  298.         ddrval = d3dapp->lpBackBuffer->BltFast(x,y, myglobs.lpInfoBuffer, &rc,
  299.                          DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
  300.     if (ddrval != DD_OK) {
  301.         /*
  302.          * Blting the info has failed. Since it is not vital, we
  303.          * aren't going to report an error.
  304.          */
  305.         return TRUE;
  306.     }
  307.     SetRect((LPRECT)(lpExtents), x, y, x + statglobs.szInfo.cx, y + statglobs.szInfo.cy);
  308.     ++(*count);
  309.     }
  310.     return TRUE;
  311. }
  312.