Platform SDK: DirectX |
Important Performance Note All rendering devices created by a given Direct3D object share the same physical resources. Although your application can create multiple rendering devices from a single Direct3D object, because they share the same hardware, extreme performance penalties will be incurred.
To create a Direct3D device in a C++ application, your application must first create a DirectDraw object by calling the DirectDrawCreateEx function and obtain a pointer to the IDirect3D7 interface. For details, see Accessing Direct3D. It must then call the IDirect3D7::CreateDevice method to create a Direct3D device. This method passes a pointer to the IDirect3DDevice7 interface to your application.
The following illustration shows the process for creating a Direct3D device in C++.
Note As discussed in Accessing Direct3D, the DirectDraw component comprises two COM objects. The newest object—called DirectDraw7 and created by calling the DirectDrawCreateEx function—is the only object that exposes the IDirect3D7 interface. It is the only object capable of spawning a Direct3D device that exposes the IDirect3DDevice7 interface. The Direct3DDevice object created in this manner does not expose legacy Direct3D interfaces. Applications that require previous iterations of the Direct3D device interface must use the DirectDrawCreate method to create a DirectDraw object, and then create the desired legacy objects.
This code fragment illustrates the process of creating a Direct3D rendering device that supports the IDirect3Device7 interface:
LPDIRECTDRAW7 lpDD; // IDirectDraw7 Interface LPDIRECT3D7 lpD3D; // IDirect3D7 Interface LPDIRECTDRAWSURFACE7 lpddsRender; // Rendering surface LPDIRECT3DDEVICE7 lpd3dDevice; // D3D Device HRESULT hr; // Create DirectDraw interface. // Use the current display driver. hr = DirectDrawCreateEx (NULL, (void **)&lpDD, IID_IDirectDraw7, NULL); if (FAILED (hr)) { // Code to handle the error goes here. } // Get an IDirect3D7 interface hr = lpDD->QueryInterface (IID_IDirect3D7, (void **)&lpD3D); if (FAILED (hr)) { // Code to handle the error goes here. } // // Code for the following tasks is omitted for clarity. // // Applications must set the cooperative level at this point. // Full-screen applications probably need to set the display // mode. // The primary surface should be created here. // The rendering surface must be created at this point. It is // assumed in this code fragment that, once created, the rendering // surface is pointed to by the variable lpddsRender. // If a z-buffer is being used, it should be created here. // Direct3D device enumeration can be done at this point. hr = lpD3D->CreateDevice (IID_IDirect3DHALDevice, lpddsRender, &lpd3dDevice, NULL);
The preceding sample invokes the IDirect3D7::CreateDevice method to create the Direct3D device. In the case of this sample, a Direct3D HAL device is created if the call is successful.
The target DirectDraw rendering surface that your application creates must be created to be used as a Direct3D rendering target. To do this, it must pass a DDSURFACEDESC2 structure to the IDirectDraw7::CreateSurface method. The DDSURFACEDESC2 structure has a member called ddsCaps, which is a structure of type DDSCAPS2. The DDSCAPS2 structure contains a member named dwCaps, which must be set to DDSCAPS_3DDEVICE when IDirectDraw7::CreateSurface is invoked.
When it is used with a hardware-accelerated rendering device, the render-target surface that you use must be created in display memory (with the DDSCAPS_VIDEOMEMORY flag). Otherwise, it must be created in system memory (using the DDSCAPS_SYSTEMMEMORY flag).
Note Some popular hardware devices require that the render target and depth buffer surfaces use the same bit depth. On such hardware, if your application uses a 16-bit render-target surface, the attached depth buffer must also be 16 bits. For a 32-bit render-target surface, the depth buffer must be 32 bits, of which 8 bits can be used for stencil buffering (if needed).
If the hardware upon which your application is running has this requirement and your application fails to meet it, any attempts to create a rendering device that uses the noncompliant surfaces fail. Use the DirectDraw method, IDirectDraw7::GetDeviceIdentifier to track hardware that imposes this limitation.
To create a Direct3D device, your application must first initialize the DirectDraw object in the normal manner and obtain a reference to the Direct3D7 class. For details, see Accessing Direct3D. It must then call the Direct3D7.CreateDevice method to create a Direct3D device. The method returns a reference to a Direct3DDevice7 class object.
The following figure illustrates the process for creating a Direct3D device from a Visual Basic application.
The following code fragment illustrates this process.
' For this example, the g_dx variable contains a valid ' reference to a DirectX7 object. Private Sub Test() On Local Error Resume Next Dim ddraw As DirectDraw7 ' DirectDraw7 class Dim d3d As Direct3D7 ' Direct3D3 class Dim ddsRender As DirectDrawSurface7 ' Rendering surface Dim d3dDev As Direct3DDevice7 ' Direct3D Device ' Create DirectDraw7 object. ' Use the current display driver. Set ddraw = g_dx.DirectDrawCreate("") If Err.Number <> DD_OK Then ' Code to handle the error goes here. End If ' Get a Direct3D7 object. Set d3d = ddraw.GetDirect3D If Err.Number <> DD_OK Then ' Code to handle the error goes here. End If ' ' Code for the following tasks is omitted for clarity. ' ' + Applications need to set the cooperative level at this point. ' + Full-screen applications probably need to set the display ' mode. ' + The primary surface should be created here. ' + The rendering surface must be created at this point. It is ' assumed in this code fragment that, once created, the ' rendering surface is referred to by the variable ddsRender. ' + If a depth-buffer is being used, it should be created here. ' + Direct3D device enumeration can be done at this point. Set d3dDev = d3d.CreateDevice("IID_IDirect3DHALDevice", ddsRender) End Sub
This code fragment invokes the Direct3D7.CreateDevice method to create the Direct3D device. In this case, a Direct3D HAL device is created if the call is successful.
The target DirectDraw rendering surface that your application creates must be created for use as a Direct3D rendering target. To do this, it must pass a DDSURFACEDESC2 variable to the DirectDraw7.CreateSurface method. The DDSURFACEDESC2 type has a member called ddsCaps, which is of type DDSCAPS2. The DDSCAPS2 type contains a member named lCaps, which must be set to DDSCAPS_3DDEVICE when DirectDraw7.CreateSurface is invoked.
To be used with a hardware-accelerated rendering device, the render-target surface that you use must be created in display memory (with the DDSCAPS_VIDEOMEMORY flag). Otherwise, it must be created in system memory (using the DDSCAPS_SYSTEMMEMORY flag).
Note Some popular hardware devices require that the render target and depth buffer surfaces use the same bit depth. On such hardware, if your application uses a 16-bit render-target surface, the attached depth buffer must also be 16 bits. For a 32-bit render-target surface, the depth buffer must be 32 bits, of which 8 bits can be used for stencil buffering, if needed.
If the hardware upon which your application is running has this requirement and your application fails to meet it, any attempts to create a rendering device that uses the noncompliant surfaces fail.