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


First, the Direct3DRM CreateLightRGB() function is used to initialize the spotlight pointer. The D3DRMLIGHT_SPOT constant is used to indicate that we are creating a spotlight. We are using 0.8 for the light’s red, green, and blue color components, indicating a light that is bright gray in color.

Next, the OnBeamNormal() function is called. The OnBeamNormal() function is a message handler for the Beam|Normal menu selection. We invoke it here to assign the spotlight umbra and penumbra angles. We’ll look at the OnBeamNormal() function soon.

Step 4 is the creation of the frame to which we will attach the spotlight:

LPDIRECT3DRMFRAME lightframe;
d3drm->CreateFrame( scene, &lightframe );
lightframe->SetPosition( scene,
        D3DVALUE(0), D3DVALUE(10), D3DVALUE(-10) );
lightframe->SetOrientation( scene,
        D3DVALUE(0), D3DVALUE(-1), D3DVALUE(1),
        D3DVALUE(0), D3DVALUE(1), D3DVALUE(0) );
lightframe->AddLight( spotlight );
lightframe->AddMoveCallback( MoveLight, NULL );
lightframe->Release();
lightframe=0;

The lightframe pointer is initialized with the Direct3DRM CreateFrame() function. The SetPosition() function is then used to position the frame 10 units above and 10 units behind the origin. The SetOrientation() function is used to point the light at the origin.

Next, the previously created spotlight is attached to the new frame with the AddLight() function. Also, the MoveLight() callback function is installed with the AddMoveCallback() function. Lastly, the lightframe pointer is released.

The fifth and final step that the CreateScene() function performs is the creation of a viewport:

d3drm->CreateFrame( scene, &camera );
camera->SetPosition( scene,
        D3DVALUE(0), D3DVALUE(6), D3DVALUE(-6) );
camera->SetOrientation( scene,
        D3DVALUE(0), D3DVALUE(-1), D3DVALUE(1.1),
        D3DVALUE(0), D3DVALUE(1), D3DVALUE(0) );
d3drm->CreateViewport( device, camera, 0, 0,
        device->GetWidth(), device->GetHeight(),
        &viewport );

First, the camera frame is initialized. Then, the frame is positioned six units above and six units behind the origin. The SetOrientation() function is used to point the camera frame toward the origin. Finally, the Direct3DRM CreateViewport() function is used to initialize the viewport pointer.

The SpotlightWin::MoveLight() Function

The Spotlight demo’s CreateScene() function installs the MoveLight() callback function. MoveLight() calculates a new orientation for the spotlight frame for each scene update. The MoveLight() function looks like this:

void SpotlightWin::MoveLight(LPDIRECT3DRMFRAME frame, void*, D3DVALUE)
{
    static const D3DVALUE LIM = D3DVALUE(0.3);
    static D3DVALUE xi = D3DVALUE(0.03);
    static D3DVALUE yi = D3DVALUE(0.04);
    static D3DVALUE x, y;
    if (x<-LIM || x>LIM)
        xi=-xi;
    if (y<-LIM || y>LIM)
        yi=-yi;
    x+=xi;
    y+=yi;
    frame->SetOrientation( NULL,
        x, y-1, D3DVALUE(1),
        D3DVALUE(0), D3DVALUE(1), D3DVALUE(0) );
}

Like the Jade demo in Chapter 5, the Spotlight demo uses a simple “bouncing ball” algorithm to perform animation (we’ll study more sophisticated animation techniques in Chapter 7). The static values that are declared in the MoveLight() function are used to track and limit the frame’s orientation. Once a new orientation is calculated, it is installed with the SetOrientation() function.

The Spotlight Demo Render Functions

Early in this chapter, when we studied ambient light by creating the AmbientLight project, we looked at the six member functions that implemented the demo’s Render menu. These functions used the Direct3DRMMeshBuilder GetQuality() and SetQuality() functions. This strategy won’t work with the Spotlight demo because we are using the Direct3DRMMesh interface.

The Direct3DRMMesh interface is almost entirely dedicated to the manipulation of groups. Groups are sets of faces within a mesh that can be modified as a single entity. The Direct3DRMMesh interface provides GetGroupColor() and SetGroupColor() member functions that allow the color of a group of faces to be inspected and assigned. The only trouble is that these functions expect identifiers that indicate which group of faces within the mesh we are interested in.

These group identifiers are important when you are using a mesh that has multiple groups, as you will see in Chapter 8. For now, however, all of the faces in each of our three meshes belong to the same group. Luckily for us, meshes that use only one group use zero as the group identifier. This default group identifier is used in the following Spotlight demo functions:

void SpotlightWin::OnRenderWireframe()
{
    mesh1->SetGroupQuality( 0, D3DRMRENDER_WIREFRAME );
    mesh2->SetGroupQuality( 0, D3DRMRENDER_WIREFRAME );
    mesh3->SetGroupQuality( 0, D3DRMRENDER_WIREFRAME );
}
void SpotlightWin::OnRenderFlat()

{
    mesh1->SetGroupQuality( 0, D3DRMRENDER_FLAT );
    mesh2->SetGroupQuality( 0, D3DRMRENDER_FLAT );
    mesh3->SetGroupQuality( 0, D3DRMRENDER_FLAT );
}

void SpotlightWin::OnRenderGouraud()
{
    mesh1->SetGroupQuality( 0, D3DRMRENDER_GOURAUD );
    mesh2->SetGroupQuality( 0, D3DRMRENDER_GOURAUD );
    mesh3->SetGroupQuality( 0, D3DRMRENDER_GOURAUD );
}

void SpotlightWin::OnUpdateRenderWireframe(CCmdUI* pCmdUI)
{
    D3DRMRENDERQUALITY quality=mesh1->GetGroupQuality( 0 );
    pCmdUI->SetCheck( quality==D3DRMRENDER_WIREFRAME );
}

void SpotlightWin::OnUpdateRenderFlat(CCmdUI* pCmdUI)
{
    D3DRMRENDERQUALITY quality=mesh1->GetGroupQuality( 0 );
    pCmdUI->SetCheck( quality==D3DRMRENDER_FLAT );
}

void SpotlightWin::OnUpdateRenderGouraud(CCmdUI* pCmdUI)
{
    D3DRMRENDERQUALITY quality=mesh1->GetGroupQuality( 0 );
    pCmdUI->SetCheck( quality==D3DRMRENDER_GOURAUD );
}

The first three functions are called when the user selects the menu options from the demo’s Render menu. The SetGroupQuality() function is used to change the rendering method for the meshes. The second three functions are called by MFC before the Render menu is displayed. The SetCheck() function is used to activate the check mark that appears to the left of the current menu item.


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.