The enumDeviceFunc Callback Function

The enumDeviceFunc callback function is of the D3DENUMDEVICESCALLBACK type, as defined in the D3dcaps.h header file. The system calls this function with identifiers and names for each Direct3D driver in the system, as well as the hardware and emulated capabilities of the driver.

The callback function uses the dcmColorModel member of the D3DDEVICEDESC structure to determine whether to examine the hardware or emulated driver description; if the member has been filled by the hardware description, the function consults the hardware description.

Next, the callback function determines whether the driver being enumerated can render in the current bit depth. If not, the function returns D3DENUMRET_OK to skip the rest of the process for this driver and continue the enumeration with the next driver. The callback function uses the locally defined BPPToDDBD function to compare the reported bit depth against the bits-per-pixel retrieved by the call to the GetDeviceCaps function in the InitApp function. (BPPToDDBD stands for bits-per-pixel to DirectDraw bit-depth.) For the code for this function, see The BPPToDDBD Helper Function.

If the driver being enumerated passes a few simple tests, other parts of D3DDEVICEDESC are examined. The callback function will choose hardware over software emulation, and RGB lighting capabilities over monochromatic lighting capabilities.

/////////////////////////////////////////////////////////////////////

//

// enumDeviceFunc

// Callback function that records each usable D3D driver's name

// and GUID. Chooses a driver and sets *lpContext to this driver.

//

/////////////////////////////////////////////////////////////////////

static HRESULT

WINAPI enumDeviceFunc(LPGUID lpGuid, LPSTR lpDeviceDescription,

LPSTR lpDeviceName, LPD3DDEVICEDESC lpHWDesc,

LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)

{

static BOOL hardware = FALSE; // Current start driver is hardware

static BOOL mono = FALSE; // Current start driver is mono light

LPD3DDEVICEDESC lpDesc;

int *lpStartDriver = (int *)lpContext;

// Decide which device description should be consulted.

lpDesc = lpHWDesc->dcmColorModel ? lpHWDesc : lpHELDesc;

// If this driver cannot render in the current display bit-depth,

// skip it and continue with the enumeration.

if (!(lpDesc->dwDeviceRenderBitDepth & BPPToDDBD(myglobs.BPP)))

return D3DENUMRET_OK;

// Record this driver's name and GUID.

memcpy(&myglobs.DriverGUID[myglobs.NumDrivers], lpGuid,

sizeof(GUID));

lstrcpy(&myglobs.DriverName[myglobs.NumDrivers][0], lpDeviceName);

// Choose hardware over software, RGB lights over mono lights.

if (*lpStartDriver == -1) {

// This is the first valid driver.

*lpStartDriver = myglobs.NumDrivers;

hardware = lpDesc == lpHWDesc ? TRUE : FALSE;

mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;

} else if (lpDesc == lpHWDesc && !hardware) {

// This driver is hardware and the start driver is not.

*lpStartDriver = myglobs.NumDrivers;

hardware = lpDesc == lpHWDesc ? TRUE : FALSE;

mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;

} else if ((lpDesc == lpHWDesc && hardware ) ||

(lpDesc == lpHELDesc && !hardware)) {

if (lpDesc->dcmColorModel == D3DCOLOR_MONO && !mono) {

// This driver and the start driver are the same type, and

// this driver is mono whereas the start driver is not.

*lpStartDriver = myglobs.NumDrivers;

hardware = lpDesc == lpHWDesc ? TRUE : FALSE;

mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;

}

}

myglobs.NumDrivers++;

if (myglobs.NumDrivers == MAX_DRIVERS)

return (D3DENUMRET_CANCEL);

return (D3DENUMRET_OK);

}