![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
The UpdateFPSSurface() FunctionThe UpdateFPSSurface() function is called for each screen update, as shown in Listing 10.13. Listing 10.13 The UpdateFPSSurface() function. BOOL FullScreenWin::UpdateFPSSurface() { static const long interval=100; static long framecount; framecount++; if (framecount==interval) { static DWORD timenow; static DWORD timethen; timethen=timenow; timenow=timeGetTime(); double seconds=double(timenow-timethen)/(double)1000; int fps=(int)((double)framecount/seconds); static char buf[10]; int len=sprintf( buf, "FPS: %d", fps); HDC hdc; fpssurf->GetDC( &hdc ); SelectObject( hdc, smallfont ); SetTextColor( hdc, RGB(255,255,255) ); SetBkColor( hdc, RGB(0,0,0) ); SetBkMode( hdc, OPAQUE ); ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &fpsrect, buf, len, 0 ); fpssurf->ReleaseDC( hdc ); displayfps=TRUE; framecount=0; } return TRUE; } This function uses a static counter variable (framecount) to count the number of screen updates, or frames. When the frame count reaches 100 (an arbitrary delay), the FPS for the last 100 frames is calculated and displayed. The high-performance Win32 multimedia timeGetTime() function is used to determine the amount of time that has elapsed since the previous FPS calculation. A string containing the calculated FPS is created and used to draw text on the fpssurf surface. Once the surface has been updated, the framecount variable is reset to zero. The Render() FunctionNow, its time to look at how the visual output from our demo is created and displayed. The Render() function is called by the RMApp::OnIdle() function, and is responsible for updating the back buffer surface and performing a page flip. The Render() function is shown in Listing 10.14. Listing 10.14 The Render() function. void FullScreenWin::Render() { if ( primsurf->IsLost() == DDERR_SURFACELOST ) { TRACE("Restoring primsurf...\n"); primsurf->Restore(); } if ( menusurf->IsLost() == DDERR_SURFACELOST ) { TRACE("Restoring menusurf...\n"); menusurf->Restore(); UpdateMenuSurface(); } if ( fpssurf->IsLost() == DDERR_SURFACELOST ) { TRACE("Restoring fpssurf...\n"); fpssurf->Restore(); } DDBLTFX bltfx; memset( &bltfx, 0, sizeof(bltfx) ); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = 0; backsurf->Blt( 0, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx ); scene->Move(D3DVALUE(1.0)); viewport->Clear(); viewport->Render( scene ); device->Update(); UpdateFPSSurface(); if (displayfps) { DWORD w, h, d; GetCurDisplayModeDims( w, h, d ); backsurf->BltFast( w-fpsrect.right, h-fpsrect.bottom, fpssurf, &fpsrect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT ); } backsurf->BltFast( 0, 0, menusurf, &menurect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT ); primsurf->Flip( 0, DDFLIP_WAIT ); } The first portion of the function is dedicated to the loss of surfaces. Surface loss occurs when the memory used by a surface is required by Windows for another purpose. Only the surface memory is lost, not the surface itself. Surface loss typically occurs when the ALT+TAB sequence is used to switch to another program. The DirectDrawSurface IsLost() function returns TRUE if the surface memory has been lost. Recovering the surface memory is fairly simple. The DirectDrawSurface Restore() function must be called. This reclaims the surface memory, but it does not restore the contents of the memory. Notice how the display mode menu surface is restored: if ( menusurf->IsLost() == DDERR_SURFACELOST ) { TRACE("Restoring menusurf...\n"); menusurf->Restore(); UpdateMenuSurface(); } If surface loss has occurred, the Restore() function is called. This recovers the surface memory, but a call to the UpdateMenuSurface() function is necessary to restore the surfaces contents. Next, the contents of the backsurf surface are erased: DDBLTFX bltfx; memset( &bltfx, 0, sizeof(bltfx) ); bltfx.dwSize = sizeof(bltfx); bltfx.dwFillColor = 0; backsurf->Blt( 0, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx ); Similar code is used in the RMWin::ClearSurface() function. The Blt() function is used to perform a color fill. The fill color is zero, but no color key has been assigned to this surface so the surface pixels are all set to zero. Now, the Direct3D portion of the scene can be drawn: scene->Move(D3DVALUE(1.0)); viewport->Clear(); viewport->Render( scene ); device->Update();
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. |