Creating a 3D Application

[Previous] [Next]

Now that you've learned the basics of 3D primitives and the render states you can use to affect how the primitives are rendered, let's look at a program that actually renders something interesting! The RoadRage code for this chapter is a lot bigger than in previous chapters, but the steps that it is taking should make sense to you. Aside from all the initialization and Windows code that we've talked about in previous chapters, here's how RoadRage works.

Loading the Models

For simple programs, you can specify the 3D models in the code itself. But for a significant 3D program, you'll probably want to load 3D model information from external files. In RoadRage, the function CMyD3DApplication::LoadRR_Resources loads all the media that the program will use. LoadRR_Resources and CMyD3DApplication::InitRRVariables, which sets up some application state, are called by WinMain before calling CMyD3DApplication::Run to start the main message loop. You could also load the media in the CMyD3DApplication::OneTimeSceneInit function.

Initializing the Device

Every time the Direct3D device is created or changed, you'll want to initialize some settings. RoadRage does this in the CMyD3DApplication::InitDeviceObjects function shown here:

 //------------------------------------------------------------------- // Name: InitDeviceObjects // Desc: Initializes scene objects //------------------------------------------------------------------- HRESULT CMyD3DApplication::InitDeviceObjects() {     // Create and set up the object material.     D3DMATERIAL7 mtrl;     D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f, 0.0f );     mtrl.power = 40.0f;     m_pd3dDevice->SetMaterial( &mtrl );     m_pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT,                                    0x00505050 );          // Set the transform matrices.     D3DUtil_SetIdentityMatrix( matWorld );     D3DUtil_SetProjectionMatrix( matProj, 1.57f,                                   1.0f, 1.0f, 100.0f );     m_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD,                                 &matWorld );     m_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION,                                  &matProj );     // Turn on lighting. Light will be set during the FrameMove()      // call.     m_pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING,                                    bEnableLighting );     // Set miscellaneous render states.     m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE);      m_pd3dDevice->SetRenderState(D3DRENDERSTATE_CULLMODE,                                   D3DCULL_NONE);     m_pd3dDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);     m_pd3dDevice->SetRenderState(D3DRENDERSTATE_FILLMODE,                                   D3DFILL_SOLID);     m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE,                                   D3DSHADE_GOURAUD);              return S_OK; } 

You can see that it sets the material on the device to be a normal white material. Then it sets the ambient light level. Then it sets up the world and projection matrices. (The view matrix will be set later.) Finally, it sets some render states to affect how the graphics will be rendered.

Handling Per-Frame Activity

Before rendering each frame, the program needs to react to user input, update object positions, and so on. In RoadRage, this is all handled in the CMyD3DApplication::FrameMove function. We haven't added input support to RoadRage, so the function doesn't do much yet. But you can see that at the end of the function, it adjusts the view matrix based on the user's position and orientation.

Rendering the Frame

After updating the world state, it's time to render the scene. This task is done by CMyD3DApplication::Render. RoadRage uses a culling system that renders a subset of the world depending on the camera's position and orientation. Management of that culling system takes up a lot of the code in this function, but the core tasks in Render are pretty simple:

  1. Call IDirect3DDevice7::Clear to clear the back buffer and the depth buffer.
  2. Decide which objects to render.
  3. Call IDirect3DDevice7::BeginScene to indicate that rendering is about to begin.
  4. Use the DrawPrimitive functions to render all the 3D objects.
  5. Call EndScene to indicate that all primitives for the frame have been submitted.


Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net