![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
The viewport is created with the CreateViewport() function. The first argument is the device that was created with the CreateDevice() function. The second argument is the camera frame that we just created. The next four arguments specify the position and dimensions of the viewport. The position is 0, 0, (the top/left corner of the device) and the dimensions are the same as the device dimensions (recall when the device was created, we used the window client area dimensions). The last argument is the address of the pointer that will point to the new viewport. Finally, the CreateScene() function returns TRUE to indicate to the RMWin class that the scene has been created successfully. Maintaining ScenesSo far, weve followed our sample program through the initialization of Direct3D and the creation of a complete scene. Lets turn our attention now to what happens during program execution. The OnIdle() FunctionThe Direct3DRM interface provides a Tick() member function that can be used to signal Direct3D to update all of the objects in a scene and then render and display a new image based on the results. The Tick() function drives Direct3D applications. Our program uses the OnIdle() function to call Tick(). The OnIdle() function is called by MFC whenever there are no messages to be processed. Calling Tick() from an OnIdle() function means that system updates are performed as often as possible. The OnIdle() function looks like this: BOOL RMApp::OnIdle(LONG) { ASSERT( RMWin::d3drm ); RMWin::d3drm->Tick( D3DVALUE(1) ); return TRUE; } The function first insures that the RMWin::d3drm data member has been initialized. If so, the Tick() function is called. The function returns TRUE to notify MFC that further OnIdle() invocations are expected (returning FALSE causes MFC to stop calling OnIdle()). The Tick() function can be used to control an applications speed in two ways. First, as mentioned previously, the more often Tick() is called, the more often Direct3D updates itself. There is, of course, a limit to how often the Tick() function can be called. If your program is running on a slow machine, the time it takes for the Tick() function to execute will increase. The second way to control a programs speed is with the argument that the Tick() function expects. Using an argument of 1.0 means that the system will do a full update and display the results. Sending a reduced value causes Direct3D to update the animation in a scene according to the arguments value. For example, if we construct a scene that contains an object that rotates one quarter turn on each update and use a Tick() argument of 0.5, the objects rotation is cut in half. Two system updates will be required to rotate the object a quarter turn. Likewise, if you use 2 as an argument, the animation in a scene will run at double speed. The ability to slow and speed the applications internal update rate means that programs can be written so that they perform animation at the exact same speed on any system, regardless of the number of screen updates. On a slow machine, the program can use large Tick() arguments to compensate for the lack of screen updates. On a fast system, small Tick() values can be used to control the application speed while letting the screen update speed run as fast as possible. Practically speaking, if a computer is capable of fewer than 10 or 15 screen updates per second, the application will be irritating despite the fact that the animation speed is correct. The OnActivate() FunctionIn general, Direct3D is pretty cooperative and does what you tell it to do. It does, however, make a few demands. One of these demands is that you tell it whenever your application receives a WM_ACTIVATE message. Direct3D provides a HandleActivate() function for this purpose. The only problem is that the HandleActivate() function is part of the Direct3DRMWinDevice interface, and we dont have such an interface in our program. The Direct3DRMWinDevice interface is supported by the same object that supports the Direct3DRMDevice interface, so we can solve our problem by using the existing Direct3DRMDevice interface to acquire the Direct3DRMWinDevice interface. The RMWin::OnActivate() function is charged with the responsibility of acquiring the WinDevice interface and calling the HandleActivate() member function: void RMWin::OnActivate(UINT state, CWnd* other, BOOL minimize) { LPDIRECT3DRMWINDEVICE windev; if (device) { if (device->QueryInterface( IID_IDirect3DRMWinDevice, (void**)&windev)==0 ) { if (windev->HandleActivate((unsigned short) MAKELONG((WORD)state,(WORD)0))!=0) AfxMessageBox("windev->HandleActivate() failure"); windev->Release(); } else AfxMessageBox("device->QueryInterface(WinDevice) failure"); } CFrameWnd::OnActivate(state, other, minimize); } We use the IID_IDirect3DRMWinDevice GUID to indicate to the QueryInterface() function that we are seeking a pointer to a Direct3DRMWinDevice interface. Once we have a pointer to the interface, we can call the HandleActivate() function. Both QueryInterface() and HandleActivate() return zero if successful.
|
![]() |
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. |