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 InitDisplayMode() Function

The InitDisplayMode() function uses DirectDraw to determine which display modes are supported by the installed video card. This data is used to create a list of display modes. The list is then used to determine an initial display mode. The InitDisplayMode() function appears in Listing 10.3.

Listing 10.3 The InitDisplayMode() function.

BOOL RMWin::InitDisplayMode()
{
    curdisplaymode=0;

    CDC* dc=GetDC();
    DWORD curdisplaydepth=dc->GetDeviceCaps( BITSPIXEL );
    dc->DeleteDC;

    ddraw->EnumDisplayModes( 0, 0, 0, DisplayModeAvailable );
    qsort( displaymode, totaldisplaymodes, sizeof(videomode),
            CompareModes );

    for ( int i=0; i<totaldisplaymodes; i++ )
    {
        DWORD w, h, d;
        GetDisplayModeDims( i, w, h, d );
        if (w==640 && h==480 && d==curdisplaydepth)
            curdisplaymode=i;
    }

    GetDisplayModeDims( curdisplaymode,
            modewidth, modeheight, modedepth );
    ddraw->SetDisplayMode( modewidth, modeheight, modedepth );
    return totaldisplaymodes!=0;
}

First, the function determines the current Windows display mode depth. This is retrieved with the GetDeviceCaps() function. The BITSPIXEL constant is used to indicate that we are interested in the display mode’s bits per pixel. The resulting value is stored in the curdisplaydepth variable. This value is used later in the function to select an initial display mode.

Next, the DirectDraw EnumDisplayModes() function is called. The last EnumDisplayModes() argument is a callback function that DirectDraw will invoke each time a supported display mode is detected. The InitDisplayMode() function uses the following callback function to react to detected display modes:

HRESULT WINAPI RMWin::DisplayModeAvailable(LPDDSURFACEDESC desc, LPVOID)
{
    int& count=totaldisplaymodes;
    if (count==MAXDISPLAYMODES)
        return DDENUMRET_CANCEL;

    displaymode[count].width=desc->dwWidth;
    displaymode[count].height=desc->dwHeight;
    displaymode[count].depth=desc->ddpfPixelFormat.dwRGBBitCount;

    count++;
    return DDENUMRET_OK;
}

The DisplayModeAvailable() callback function receives a pointer to a DDSURFACEDESC structure. This structure describes the detected mode. The callback function uses the structure to initialize elements of the displaymode array. After the element has been initialized, the totaldisplaymodes variable is incremented (via the count alias). Finally, the DDENUMRET_OK constant is returned, indicating that DirectDraw should continue searching for supported display modes. Using DDRNUMRET_CANCEL as a return value causes DirectDraw to discontinue display mode enumeration.

Returning to the InitDisplayMode() function, after all available display modes have been detected, the Win32 qsort() function is used to sort the array of display modes. The function call looks like this:

qsort( displaymode, totaldisplaymodes, sizeof( videomode ), CompareModes );

The displaymode array, the total number of display modes, the size of each displaymode element, and a comparison function are all passed to the qsort() function. The comparison function (CompareModes()) is a callback function invoked by qsort() to determine correct order. The CompareModes() function appears as shown in Listing 10.4.

Listing 10.4 The CompareModes() function.

int RMWin::CompareModes( const void *arg1, const void *arg2 )
{
    videomode* mode1=(videomode*)arg1;
    videomode* mode2=(videomode*)arg2;

    DWORD volume1=mode1->width*mode1->height;
    DWORD volume2=mode2->width*mode2->height;

    if (volume1<volume2)
        return -1;
    else if (volume1>volume2)
        return 1;

    if (mode1->depth<mode2->depth)
        return -1;
    else if (mode1->depth>mode2->depth)
        return 1;

    return 0;
}

The CompareModes() function uses the display mode’s dimensions to compare the two modes passed as parameters. This allows the displaymode array to be sorted according to display mode dimension.

Next, an initial display mode is selected from the displaymode array:

for ( int i=0; i<totaldisplaymodes; i++ )
{
    DWORD w, h, d;
    GetDisplayModeDims( i, w, h, d );
    if (w==640 && h==480 && d==curdisplaydepth)
        curdisplaymode=i;
}

A 640×480 display mode is sought (640×480 being a display mode that virtually every video card supports). The current Windows display depth is used for the initial bit depth.

Once a display mode has been selected, its dimensions are retrieved and used to change the current display mode:

GetDisplayModeDims( curdisplaymode,
        modewidth, modeheight, modedepth );
ddraw->SetDisplayMode( modewidth, modeheight, modedepth );

The GetDisplayModeDims() function retrieves the dimensions for the display mode indicated by the first argument. The modewidth, modeheight, and modedepth variables are RMWin data members used to store the dimensions of the current video mode. Once the dimensions are retrieved, they are used as arguments to the DirectDraw SetDisplayMode() function. This function call performs the actual display mode activation and completes the task of the InitDisplayMode() function.


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.