Enumerating the DirectDraw Devices

[Previous] [Next]

In DirectX, enumeration functions such as DirectDrawEnumerateEx are used to list elements of a particular set by triggering a callback function for each element in the list. The callback function determines whether the current list item meets the criteria for the object you're attempting to create. In the RoadRage code, we'll be creating a list of all the available Direct3D devices that meet our program's criteria. As mentioned above, the code needs to enumerate the DirectDraw devices, and for each DirectDraw device, it needs to enumerate the available Direct3D devices.

By passing the flags DDENUM_ATTACHEDSECONDARYDEVICES, DDENUM_DETACHEDSECONDARYDEVICES, and DDENUM_NONDISPLAYDEVICES to the DirectDrawEnumerateEx routine, we request that these types of devices be enumerated (and thus added to the list of available devices).

The DirectDrawEnumerateEx function, which uses these flags, is declared as follows:

 HRESULT WINAPI DirectDrawEnumerateEx(     LPDDENUMCALLBACK lpCallback,     LPVOID lpContext,     DWORD dwFlags ); 

ParameterDescription
lpCallbackThe address of a callback function that will be called with a description of each DirectDraw-enabled HAL installed in the target system.
lpContextThe address of an application-defined context that is passed to the enumeration callback function each time it is called.
dwFlagsFlags specifying the enumeration scope. If the value is 0, the function will enumerate only the primary display device. This parameter can also be a combination of the following flags:

DDENUM_ATTACHEDSECONDARYDEVICES Enumerate the primary device and any display devices that are attached to the desktop.

DDENUM_DETACHEDSECONDARYDEVICES Enumerate the primary device and any display devices that are not attached to the desktop.

DDENUM_NONDISPLAYDEVICES Enumerate the primary device and any nondisplay devices, such as 3D accelerators that have no 2D capabilities.

In the Direct3D Framework, enumeration begins with D3DEnum_EnumerateDevices, a function in d3denum.cpp. The code for this routine follows:

 //------------------------------------------------------------------- // Name: D3DEnum_EnumerateDevices // Desc: Enumerates all drivers, devices, and modes. The callback  //       function is called for each device to confirm that the  //       device supports the feature set the application requires. //------------------------------------------------------------------- HRESULT D3DEnum_EnumerateDevices( HRESULT                      (*AppConfirmFn)(DDCAPS*, D3DDEVICEDESC7*) ) {     // Store the device enumeration callback function.     g_fnAppConfirmFn = AppConfirmFn;     // Enumerate drivers, devices, and modes.     DirectDrawEnumerateEx( DriverEnumCallback, NULL,                             DDENUM_ATTACHEDSECONDARYDEVICES |                            DDENUM_DETACHEDSECONDARYDEVICES |                            DDENUM_NONDISPLAYDEVICES );     // Make sure that devices were enumerated.     if( 0 == g_dwNumDevicesEnumerated )     {         DEBUG_MSG( _T("No devices and/or modes were enumerated!") );         return D3DENUMERR_ENUMERATIONFAILED;     }     if( 0 == g_dwNumDevices )     {         DEBUG_MSG( _T("No enumerated devices were accepted!") );         DEBUG_MSG( _T("Try enabling the D3D Reference Rasterizer.") );         return D3DENUMERR_SUGGESTREFRAST;     }     return S_OK; } 

The parameter AppConfirmFn that is passed into D3DEnum_EnumerateDevices is a function pointer that can be used to filter out Direct3D devices that are unsuitable for the program and will be described in greater detail later in this chapter.

DirectDrawEnumerateEx takes a function pointer as its first parameter. This should be a pointer to the application-defined callback function. In this code, it is set to the DriverEnumCallback routine. The function must be of the following form:

 BOOL WINPAPI DDEnumCallbackEx(     GUID FAR *lpGUID,     LPSTR lpDriverDescription,     LPSTR lpDriverName,     LPVOID lpContext     HMONITOR hm ); 

ParameterDescription
lpGUIDThe address of a globally unique identifier for the device
lpDriverDescriptionThe address of the device's description
lpDriverNameThe address of the device's name
lpContextThe address of the user-defined data context that was passed to DirectDrawEnumerateEx
hmThe handle to the monitor associated with the enumerated DirectDraw object. This parameter will be NULL when the enumerated DirectDraw object is for the primary device, a nondisplay device (such as a 3D accelerator with no 2D capabilities), and devices that aren't attached to the desktop.

The DriverEnumCallback function is defined in d3denum.cpp as follows:

 //------------------------------------------------------------------- // Name: DriverEnumCallback // Desc: Callback function for enumerating drivers //------------------------------------------------------------------- static BOOL WINAPI DriverEnumCallback( GUID* pGUID, TCHAR* strDesc,                                        TCHAR* strName, VOID*,                                        HMONITOR ) {     D3DEnum_DeviceInfo d3dDeviceInfo;     LPDIRECTDRAW7      pDD;     LPDIRECT3D7        pD3D;     HRESULT            hr;     //     // STEP 1      // Use the GUID to create the DirectDraw object.     //     hr = DirectDrawCreateEx( pGUID, (VOID**)&pDD, IID_IDirectDraw7,                              NULL );     if( FAILED(hr) )     {         DEBUG_MSG( _T("Can't create DDraw during enumeration!") );         return D3DENUMRET_OK;     }     //     // STEP 2     // Create a Direct3D object to enumerate the d3d devices.     //     hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&pD3D );     if( FAILED(hr) )     {         pDD->Release();         DEBUG_MSG( _T("Can't query IDirect3D7 during enumeration!") );         return D3DENUMRET_OK;     }     //     // STEP 3     //     // Copy data to a device information structure.     ZeroMemory( &d3dDeviceInfo, sizeof(d3dDeviceInfo) );     lstrcpyn( d3dDeviceInfo.strDesc, strDesc, 39 );     d3dDeviceInfo.ddDriverCaps.dwSize = sizeof(DDCAPS);     d3dDeviceInfo.ddHELCaps.dwSize    = sizeof(DDCAPS);     pDD->GetCaps( &d3dDeviceInfo.ddDriverCaps,                   &d3dDeviceInfo.ddHELCaps );     if( pGUID )     {         d3dDeviceInfo.guidDriver = (*pGUID);         d3dDeviceInfo.pDriverGUID = &d3dDeviceInfo.guidDriver;     }     strcpy(D3Ddevicename, d3dDeviceInfo.strDesc);     // Record whether the device can render into a desktop window.     if( d3dDeviceInfo.ddDriverCaps.dwCaps2          & DDCAPS2_CANRENDERWINDOWED )         if( NULL == d3dDeviceInfo.pDriverGUID )             d3dDeviceInfo.bDesktopCompatible = TRUE;     //     // STEP 4     // Enumerate the full-screen display modes.     //     pDD->EnumDisplayModes( 0, NULL, &d3dDeviceInfo,                            ModeEnumCallback );     // Sort the list of display modes.     qsort( d3dDeviceInfo.pddsdModes, d3dDeviceInfo.dwNumModes,            sizeof(DDSURFACEDESC2), SortModesCallback );     // Now enumerate all the 3D devices.     pD3D->EnumDevices( DeviceEnumCallback, &d3dDeviceInfo );     // Clean up and return.     SAFE_DELETE( d3dDeviceInfo.pddsdModes );     pD3D->Release();     pDD->Release();     return DDENUMRET_OK; } 

As each DirectDraw device is enumerated, DriverEnumCallback gets called by DirectX, with the appropriate GUID, description, name, and monitor handle for each device. As you can see, the first thing DriverEnumCallback does with this information is to create a DirectDraw object for each device.



Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net