![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
The code for the first step looks like this: D3DRMLOADRESOURCE resinfo; resinfo.hModule=NULL; resinfo.lpName=MAKEINTRESOURCE( IDR_D3DMESH ); resinfo.lpType="MESH"; d3drm->CreateMeshBuilder( &meshbuilder ); meshbuilder->Load( &resinfo, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL ); meshbuilder->SetQuality( D3DRMRENDER_FLAT ); ScaleMesh( meshbuilder, D3DVALUE(25) ); A default mesh is stored in the demos resources and identified by the IDR_D3DMESH constant. Although the CreateScene() function loads this internal mesh automatically, this mesh can be replaced using the File|Open menu selection. Notice that the SetQuality() function is used to change the meshs rendering method to flat. The flat rendering method is used because individual faces are more distinct with the flat method than with other rendering methods. Step 2 is the creation of a frame for the mesh: d3drm->CreateFrame( scene, &meshframe ); meshframe->SetRotation( scene, D3DVALUE(1), D3DVALUE(0), D3DVALUE(0), D3DVALUE(.05) ); meshframe->AddVisual( meshbuilder ); meshframe->AddMoveCallback( UpdateDrag, NULL ); The meshframe pointer is a FacePickWin data member, so it is not declared within the CreateScene() function. The pointer is initialized with the Direct3DRM CreateFrame() function. The frame is given a rotation attribute with the SetRotation() function, but this is only an initial setting. The rotation attribute can be changed at any time by rotating the mesh with the mouse (youll see how this is done when we look at the UpdateDrag() function). After the SetRotation() function is called, the previously constructed mesh is attached to the new frame with the AddVisual() function. Lastly, the UpdateDrag() callback function is installed with the AddMoveCallback() function. Next, two light sources are created: LPDIRECT3DRMLIGHT dlight; d3drm->CreateLightRGB( D3DRMLIGHT_DIRECTIONAL, D3DVALUE(1.00), D3DVALUE(1.00), D3DVALUE(1.00), &dlight ); LPDIRECT3DRMLIGHT alight; d3drm->CreateLightRGB( D3DRMLIGHT_AMBIENT, D3DVALUE(0.40), D3DVALUE(0.40), D3DVALUE(0.40), &alight ); LPDIRECT3DRMFRAME lightframe; d3drm->CreateFrame( scene, &lightframe ); lightframe->AddLight( dlight ); lightframe->AddLight( alight ); lightframe->SetOrientation( scene, D3DVALUE(0), D3DVALUE(-1), D3DVALUE(1), D3DVALUE(0), D3DVALUE(1), D3DVALUE(0) ); A directional and an ambient light are created using the Direct3DRM CreateLightRGB() function. The ambient light will emit a gray light because of the reduced RGB values used in its creation. A frame is created, and the light sources are attached with the AddLight() function. Finally, the SetOrientation() function is used to orient the directional light. The frames orientation will have no effect on the ambient light source. The fourth and final step is the creation of a viewport: d3drm->CreateFrame( scene, &camera ); camera->SetPosition( scene, D3DVALUE(0), D3DVALUE(0), D3DVALUE(-50) ); d3drm->CreateViewport( device, camera, 0, 0, device->GetWidth(), device->GetHeight(), &viewport ); The camera pointer is initialized with the Direct3DRM CreateFrame() function and positioned with the SetPosition() function. The frame is then used as an argument to the Direct3DRM CreateViewport() function. The FacePickWin Mouse FunctionsThe FacePick demo relies heavily on the mouse. The mouse is used not only to pick faces, but also to rotate and position the mesh. The FacePickWin class uses the OnLButtonDown() and OnLButtonUp() functions to track the status of the left mouse button. The OnLButtonDown() function looks like this: void FacePickWin::OnLButtonDown(UINT nFlags, CPoint point) { int faceindex=PickFace( point ); if (faceindex!=-1) { LPDIRECT3DRMFACEARRAY facearray; meshbuilder->GetFaces( &facearray ); LPDIRECT3DRMFACE face; facearray->GetElement( faceindex, &face ); face->SetColor( pickcolor ); face->Release(); facearray->Release(); } else if (!drag) { drag=TRUE; last_x = GetMouseX(); last_y = GetMouseY(); SetCapture(); ShowCursor( FALSE ); } RMWin::OnLButtonDown( nFlags, point ); } The first thing that the OnLButtonDown() function does is call the PickFace() function. PickFace() handles the actual picking operation. PickFace() is very similar to the PickMesh() function in the MeshPick demo except that PickFace() returns the index of a selected face (or -1, if no face was selected). If a face is selected, the face index is used to color the face. First, the Direct3DRMMeshBuilder GetFaces() function is used to retrieve an array of faces. The index of the selected face is used to retrieve a pointer to the face that was selected. The Direct3DRMFace SetColor() function is used to change the faces color. If no face is selected, a drag sequence is initiated. In the MeshPick demo, drag operations were used to move the selected mesh. In the FacePick demo, a drag operation is used to rotate the mesh. Here, when a drag sequence is started, the current mouse position is stored with the last_x and last_y data members, and the SetCapture() and ShowCursor() functions are called. Now, lets look at the OnLButtonUp() function: void FacePickWin::OnLButtonUp(UINT nFlags, CPoint point) { if (drag) { end_drag=TRUE; ReleaseCapture(); ShowCursor( TRUE ); } RMWin::OnLButtonUp( nFlags, point ); } Intuitively, you would expect the OnLButtonUp() function to terminate a drag operation (if one is in effect). Unfortunately, this would prevent one of FacePicks features. The FacePick demo allows the user to spin the displayed mesh. The mesh can be rotated during the drag operation, but it can also be set into motion by flicking the mouse and releasing the button at the same time. This feature wouldnt be possible if we terminated the drag operation here because the code needs a chance to install the latest rotation attribute. The rotation attribute code appears in the UpdateDrag() callback function. Rather than duplicate the code, we will use a flag that signals that the drag operation is to terminate. In the meantime, well restore the mouse cursor and mouse capture state, as these settings do not affect the rotation attribute code.
|
![]() |
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. |