Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Cutting Edge Direct 3D Programming
(Publisher: The Coriolis Group)
Author(s): Stan Trujillo
ISBN: 1576100502
Publication Date: 11/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


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 demo’s 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. We’ll omit discussion of these steps in this chapter.

The Cube2Win::UpdateCube() Function

The UpdateCube() function serves two purposes. It performs vertex animation, and it periodically changes the mesh’s 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 mesh’s 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 group’s 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 group’s 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 demo’s UpdateCube() function.

The Cube2Win::UpdateColors() Function

The 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 group’s current color. Once the clr value has been determined, it is installed with the Direct3DRMMesh SetGroupColorRGB() function. Only the red portion of the mesh group’s color is animated. The green and blue portions are always zero.

The Cube2Win Render Functions

The 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 submenus—one for each mesh group. This menu structure appears in Figure 8.3.


Figure 8.3  The Cube2 Render menu.

Twelve functions are required to implement the Cube2 demo’s 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 group’s rendering setting is flat.


Previous Table of Contents Next


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.