![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
The frame is created with the Direct3DRM CreateFrame() function and used to place the mesh. The frame is then given a rotation attribute. Next, a static instance of the CallbackData structure is initialized. The structure has been modified to include mesh identifiers for both of the demos mesh groups. The Direct3DRMFrame AddMoveCallback() function is used to install two callback functions: UpdateCube() and UpdateColors(). Each callback function will be supplied with the pointer to the callback data structure whenever it is invoked. The UpdateCube() function will perform vertex animation for both mesh groups. The UpdateColors() function will perform color animation for the second mesh group. Steps 4 and 5 create two light sources and a viewport. Well omit discussion of these steps in this chapter. The Cube2Win::UpdateCube() FunctionThe UpdateCube() function serves two purposes. It performs vertex animation, and it periodically changes the meshs rotational attributes: void Cube2Win::UpdateCube(LPDIRECT3DRMFRAME frame, void* p, D3DVALUE) { CallbackData* data=(CallbackData*)p; static const D3DVALUE lim=D3DVALUE(5); static D3DVALUE control; static D3DVALUE inc=D3DVALUE(.25); static D3DRMVERTEX vert[12]; data->mesh->GetVertices( data->group1, 0, 12, vert ); vert[0].position.x+=inc; vert[0].position.y+=inc; vert[0].position.z+=inc; vert[6].position.x+=inc; vert[6].position.y+=inc; vert[6].position.z+=inc; vert[8].position.x+=inc; vert[8].position.y+=inc; vert[8].position.z+=inc; data->mesh->SetVertices( data->group1, 0, 12, vert ); data->mesh->GetVertices( data->group2, 0, 12, vert ); vert[2].position.x+=inc; vert[2].position.y+=inc; vert[2].position.z+=inc; vert[6].position.x+=inc; vert[6].position.y+=inc; vert[6].position.z+=inc; vert[8].position.x+=inc; vert[8].position.y+=inc; vert[8].position.z+=inc; data->mesh->SetVertices( data->group2, 0, 12, vert ); control+=inc; if (control>lim || control<-lim) inc=-inc; static UINT delay; if (++delay<20) return; delay=0; LPDIRECT3DRMFRAME scene; frame->GetScene( &scene ); D3DVECTOR spinvect; D3DRMVectorRandom( &spinvect ); D3DVALUE spin=D3DDivide( rand()%50+1, 400 ); frame->SetRotation( scene, spinvect.x, spinvect.y, spinvect.z, spin ); } The UpdateCube() function uses static variables to update the meshs vertex locations: static const D3DVALUE lim=D3DVALUE(5); static D3DVALUE control; static D3DVALUE inc=D3DVALUE(.25); static D3DRMVERTEX vert[12]; The lim, control, and inc variables are used to control the vertex animation. The vert array is used as temporary storage for each mesh groups vertex data. Notice that the array has 12 entries; in the Cube demo, the vert array had 24. Each of the two mesh groups contains vertices that are animated, so the GetVertices() and SetVertices() functions are used to adjust each mesh groups settings: data->mesh->GetVertices( data->group1, 0, 12, vert ); vert[0].position.x+=inc; vert[0].position.y+=inc; vert[0].position.z+=inc; vert[6].position.x+=inc; vert[6].position.y+=inc; vert[6].position.z+=inc; vert[8].position.x+=inc; vert[8].position.y+=inc; vert[8].position.z+=inc; data->mesh->SetVertices( data->group1, 0, 12, vert ); data->mesh->GetVertices( data->group2, 0, 12, vert ); vert[2].position.x+=inc; vert[2].position.y+=inc; vert[2].position.z+=inc; vert[6].position.x+=inc; vert[6].position.y+=inc; vert[6].position.z+=inc; vert[8].position.x+=inc; vert[8].position.y+=inc; vert[8].position.z+=inc; data->mesh->SetVertices( data->group2, 0, 12, vert ); The vert array is used to store the vertex data for both of the mesh groups. The remainder of the UpdateCube() function is the same as the Cube demos UpdateCube() function. The Cube2Win::UpdateColors() FunctionThe UpdateColors() function performs color animation for the second mesh group. The function looks like this: void Cube2Win::UpdateColors(LPDIRECT3DRMFRAME, void* p, D3DVALUE) { CallbackData* data=(CallbackData*)p; static D3DVALUE clr=D3DVALUE(.5); static D3DVALUE inc=D3DVALUE(.2); clr+=inc; if (clr<D3DVALUE(.3) || clr>D3DVALUE(1)) { inc=-inc; clr+=inc; } data->mesh->SetGroupColorRGB( data->group2, clr, D3DVALUE(0), D3DVALUE(0) ); } The clr variable is used to calculate and store the mesh groups current color. Once the clr value has been determined, it is installed with the Direct3DRMMesh SetGroupColorRGB() function. Only the red portion of the mesh groups color is animated. The green and blue portions are always zero. The Cube2Win Render FunctionsThe Cube2 demo uses a slight variation on the typical Render menu because each mesh group has its own render settings. The Render menu, therefore, contains two submenusone for each mesh group. This menu structure appears in Figure 8.3.
Twelve functions are required to implement the Cube2 demos Render menu, but the functions differ from each other only slightly. An example of a function that is invoked when a menu entry is selected looks like this: void Cube2Win::OnRenderGroup1Wireframe() { if (mesh) mesh->SetGroupQuality( group1, D3DRMRENDER_WIREFRAME ); } This function responds to the Render|Group1|Wireframe menu entry and uses the Direct3DRMMesh SetGroupQuality() function to assign the wireframe rendering method. Notice that the group1 group identifier is used as the first SetGroupQuality() argument. An example of a function that is called to activate menu check marks looks like this: void Cube2Win::OnUpdateRenderGroup1Flat(CCmdUI* pCmdUI) { if (mesh) { D3DRMRENDERQUALITY meshquality = mesh->GetGroupQuality( group1 ); pCmdUI->SetCheck( meshquality==D3DRMRENDER_FLAT ); } } This is the function that determines if the first mesh groups rendering setting is flat.
|
![]() |
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. |