The EnumDrivers Function

The EnumDrivers function is called by the InitApp function just before InitApp creates the application's scene and camera.

The IDirect3D COM interface is really an interface to a DirectDraw object, so the first thing this enumeration function does is call the DirectDrawCreate function to create a DirectDrawObject. Then EnumDrivers uses the QueryInterface method to create an IDirect3D interface. Notice that the C implementation of QueryInterface requires that you pass the address of the interface identifier as the second parameter, not simply the constant itself (as in the C++ implementation).

The enumeration is handled by the IDirect3D::EnumDevices method, which depends on the locally defined enumDeviceFunc callback function. For more information about this callback function, see The enumDeviceFunc Callback Function.

Notice that IDirect3D::EnumDevices is a Direct3D method, not a Direct3DRM method; there is no enumeration method in the Retained-Mode API. This is a good example of the natural use of both Retained-Mode and Immediate-Mode methods in a single application.

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

//

// EnumDrivers

// Enumerate the available D3D drivers and choose one.

//

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

static BOOL

EnumDrivers(HWND win)

{

LPDIRECTDRAW lpDD;

LPDIRECT3D lpD3D;

HRESULT rval;

// Create a DirectDraw object and query for the Direct3D interface

// to use to enumerate the drivers.

DirectDrawCreate(NULL, &lpDD, NULL);

rval = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirect3D,

(void**) &lpD3D);

if (rval != DD_OK) {

lpDD->lpVtbl->Release(lpDD);

return FALSE;

}

// Enumerate the drivers, setting CurrDriver to -1 to initialize the

// driver selection code in enumDeviceFunc.

myglobs.CurrDriver = -1;

lpD3D->lpVtbl->EnumDevices(lpD3D, enumDeviceFunc,

&myglobs.CurrDriver);

// Ensure at least one valid driver was found.

if (myglobs.NumDrivers == 0) {

return FALSE;

}

lpD3D->lpVtbl->Release(lpD3D);

lpDD->lpVtbl->Release(lpDD);

return TRUE;

}