Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Cutting Edge Direct 3D Programming
(Publisher: The Coriolis Group)
Author(s): Stan Trujillo
ISBN: 1576100502
Publication Date: 11/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


The UpdateMenuSurface() Function

The role of the UpdateMenuSurface() function is to initialize the contents of the display mode menu surface, as shown in Listing 10.11.

Listing 10.11 The UpdateMenuSurface() function.

BOOL FullScreenWin::UpdateMenuSurface()
{
    char buf[80];
    int len;
    RECT rect;

    ClearSurface( menusurf, 0 );

    HDC hdc;
    menusurf->GetDC( &hdc );
    SelectObject( hdc, largefont );
    SetBkMode( hdc, TRANSPARENT );

    SetTextColor( hdc, textshadow );
    ExtTextOut( hdc, 1, 1, 0, 0, headertext, strlen(headertext), 0 );
    SetTextColor( hdc, textcolor );
    ExtTextOut( hdc, 0, 0, 0, 0, headertext, strlen(headertext), 0 );

    SelectObject( hdc, smallfont );

    int nmodes=GetNumDisplayModes();
    if (nmodes>maxmodes)
        nmodes=maxmodes;

    int rows=nmodes/menucols;
    if (nmodes%menucols)
        rows++;

    for (int i=0; i<nmodes; i++)
    {
        rect.left=(i/rows)*colwidth;
        rect.top=(i%rows)*rowheight+reservedspace;
        rect.right=rect.left+colwidth;
        rect.bottom=rect.top+rowheight;

        DWORD w,h,d;
        GetDisplayModeDims( i, w, h, d );

        len=sprintf( buf, "%dx%dx%d", w, h, d );
        SetTextColor( hdc, textshadow );
        ExtTextOut( hdc, rect.left+1, rect.top+1, 0, &rect, buf,
                len, 0 );

        if (i==selectmode)
            SetTextColor( hdc, highlightcolor );
        else
            SetTextColor( hdc, textcolor );
        ExtTextOut( hdc, rect.left, rect.top, 0, &rect, buf, len, 0 );
    }

    rect.left=0;
    rect.right=319;
    rect.top=179;
    rect.bottom=199;

    len=sprintf( buf, "[Arrows]  [Enter]  [W]  [F]  [G]  [Escape]" );
    SetTextColor( hdc, textshadow );
    ExtTextOut( hdc, 1, 180, 0, &rect, buf, len, 0 );
    SetTextColor( hdc, textcolor );
    ExtTextOut( hdc, 0, 179, 0, &rect, buf, len, 0 );

    menusurf->ReleaseDC( hdc );

    return TRUE;
}

The first step that the UpdateMenuSurface() function takes is clearing the entire surface to zero. This is done with the RMWin::ClearSurface() function. Zero is passed as the second argument to ClearSurface(), indicating the desired pixel value. Because a color key of zero was specified for this surface, the entire surface is now transparent.

Next, the DirectDrawSurface GetDC() function is used to retrieve a Windows device context for the surface. The resulting HDC (Handle for a Device Context) allows us to use Windows device context functions. In our case, we are going to use the device context handle to draw text on the surface.

The bulk of the UpdateMenuSurface() function is dedicated to drawing text on the menusurf surface. First, the Win32 ExtTextOut() function is used to display a banner for the demo. Then, a string for each detected video mode is created and drawn. Finally, a list of keys that the demo responds to is displayed at the bottom of the surface.

Notice that all of the text is displayed twice, each time using a different color and a slightly different location. This creates a subtle text shadow effect.

Before the UpdateMenuSurface() function returns, the DirectDrawSurface ReleaseDC() function is called. This is very important because Windows itself is shut down between GetDC() and ReleaseDC() function calls. Forgetting to release the device context handle for a DirectDraw surface results in an impressive crash (believe me—I know!).

The CreateFPSSurface() Function

The CreateFPSSurface() function approaches surface creation a little differently than the CreateMenuSurface() function. The CreateFPSSurface() function first determines the size of the surface and then creates the surface, as shown in Listing 10.12. The surface size depends on the size of the text that is to be displayed:

Listing 10.12 The CreateFPSSurface() function.

BOOL FullScreenWin::CreateFPSSurface()
{
    static const char dummystr[]="FPS: 0000";

    HDC hdc = ::GetDC( 0 );
    SelectObject( hdc, smallfont );
    SIZE size;
    GetTextExtentPoint( hdc, dummystr, strlen(dummystr), &size );
    ::ReleaseDC( 0, hdc );

    fpsrect.left=0;
    fpsrect.top=0;
    fpsrect.right=size.cx;
    fpsrect.bottom=size.cy;

    fpssurf=CreateSurface( size.cx, size.cy );

    DDCOLORKEY  ddck;
    ddck.dwColorSpaceLowValue=0;
    ddck.dwColorSpaceHighValue=0;
    fpssurf->SetColorKey( DDCKEY_SRCBLT, &ddck );

    return TRUE;
}

A dummy string is used to determine the text size. The string is initialized with a worst-case scenario. That is, the dummy string contains more characters than the actual string will have to display. Therefore, the size of the text will be sufficient for any frame rate (up to 9,999 frames per second).

A temporary device context is created for the text size calculation. The smaller of the demos two fonts is selected, and the GetTextExtentPoint() function is used to retrieve the text size in pixels. The text size is then used to initialize the fpsrect structure and to create the fpssurf surface.

Finally, a color key is assigned to the surface. As with the display mode menu surface, pixels with values of zero are transparent.


Previous Table of Contents Next


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.