![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
The first CreateDeviceFromClipper() argument is a pointer to the DirectDrawClipper interface. The second argument is the return value from the GetGUID() member function. Well look at the GetGUID() function after we finish looking at the CreateDevice() function. The third and fourth arguments are the width and height of the client area. This causes CreateDeviceFromClipper() to create a device that will fit nicely in the window.
The address of the device data member is passed as the last argument, allowing the pointer to be modified to point to the new device. After the device has been created, it is configured to use Gouraud shading with the SetQuality() member function: device->SetQuality( D3DRMRENDER_GOURAUD ); When a device is first created, it defaults to flat shading. We are changing this setting so that our programs use Gouraud shading by default. This setting can be overridden (again) later, when we are creating the application specific interfaces. The next thing that CreateDevice() does is retrieve the pixel depth of the current video mode: HDC hdc = ::GetDC( m_hWnd ); int bpp = ::GetDeviceCaps( hdc, BITSPIXEL ); ::ReleaseDC( m_hWnd, hdc ); The GetDeviceCaps() function is used to assign the number of bits used to represent each pixel to the bpp variable. This value determines the maximum number of colors that a video mode can display at any given time. The bpp value is then used in a switch statement to assign settings to both the Direct3DRMDevice and the Direct3DRM objects. Optimum settings differ from one application to the next. The values used in CreateDevice() are good general purpose settings, but only experimentation will yield the best results for your application. Next, the root frame for the scene is created with the Direct3DRM CreateFrame() member function: r = d3drm->CreateFrame( NULL, &scene ); Technically, the root frame is part of the scene and should be created by the application specific code. Practically speaking, however, all scenes have a root frame, so its creation here is justified. Next, the CreateScene() function is called: if (CreateScene()==FALSE) { AfxMessageBox("CreateScene() failed"); return FALSE; } The CreateScene() member function is the function that the SampleWin class overrides to allow the creation of application specific scenes. The CreateScene() function can be used to create any kind of scene you want, but there is one requirement. You must initialize the camera and viewport data members. Well look at CreateScene() soon. The last four lines of the CreateDevice() function appear as follows: CreateScene(); ASSERT( camera ); ASSERT( viewport ); return TRUE; The ASSERT macro checks if the camera and viewport data members have been initialized and terminates the application with a message box if they havent. Finally, CreateDevice() returns TRUE. If you look back at listing 4.1, youll see that if any of the functions fail, a TRACE macro message is displayed and FALSE is returned. Returning FALSE notifies the RMWin class to terminate the application. The GetGUID() FunctionThe GetGUID() member function is used to retrieve a GUID (globally unique identifier) that identifies the device that is to be created by the CreateDeviceFromClipper() function. If instead of using GetGUID() we use NULL, CreateDeviceFromClipper() will choose a Ramp color model device automatically. We use GetGUID() so that we can specify either Ramp or RGB color model. The GetGUID() function appears in Listing 4.2. Listing 4.2 The GetGUID() function. GUID* RMWin::GetGUID() { static GUID* lpguid; HRESULT r; D3DFINDDEVICESEARCH searchdata; memset(&searchdata, 0, sizeof searchdata); searchdata.dwSize = sizeof searchdata; searchdata.dwFlags = D3DFDS_COLORMODEL; searchdata.dcmColorModel = colormodel; static D3DFINDDEVICERESULT resultdata; memset( &resultdata, 0, sizeof resultdata ); resultdata.dwSize = sizeof resultdata; LPDIRECTDRAW ddraw; r = DirectDrawCreate( NULL, &ddraw, NULL ); if (r!=DD_OK) { TRACE("DirectDrawCreate failed\n"); return NULL; } LPDIRECT3D d3d; r = ddraw->QueryInterface( IID_IDirect3D, (void**)&d3d ); if ( r != D3DRM_OK ) { TRACE("d3drm->QueryInterface failed\n"); ddraw->Release(); return NULL; } r=d3d->FindDevice( &searchdata, &resultdata ); if ( r==D3D_OK ) lpguid = &resultdata.guid; else { TRACE("FindDevice failure\n"); lpguid=NULL; } d3d->Release(); ddraw->Release(); return lpguid; } Before we go on, we should talk about why the GetGUID() function is as complicated as it is. Our goal is to acquire a GUID for a specific Direct3D device. It would seem that the Direct3DRM interface would supply a member function that we could use for this purpose. Perhaps Direct3D could have been designed this way, but it wasnt. We are using the Retained Mode portion of Direct3D, and Retained Mode programs rely internally on the Immediate Mode portion to do the actual rendering. The bottom line is that a Direct3D device is an Immediate Mode construct, so well have to use an Immediate Mode interface to locate the device we want. Immediate Mode functionality is accessed through the Direct3D COM interface.
|
![]() |
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. |