the DirectX eXperience Site News Articles Cheap Bookstore (20% Off!) DirectX Resources Tips Contribute here! About this Site Feedback Our Nifty Sponsors Become a Sponsor

Direct3D Retained Mode

Bipin Patwardhan
National Centre for Software Technology, Juhu, Mumbai, India.
email : bipin@ncst.ernet.in


Abstract

The DirectX technology developed by Microsoft, is a collection of APIs for developing high-performance, real-time Windows applications.

These APIs have been developed primarily to attract all the developers who have uptil now developed games and multimedia applications on MSDOS, as developing these applications on Windows makes them slow. A primary motivation behind the DirectX APIs is to allow Windows applications to rival the performace of MSDOS applications. In addition to improvement in performance, these APIs offer many other features, like sound handling, networking.

DirectX consists of DirectDraw, DirectSound, DirectPlay, Direct3D and DirectInput. Each one of these components addresses a different area required for game and multimedia application development.

In this series of tutorials, we will focus on the Direct3D component of DirectX.

Direct3D offers services for real-time 3D, to deliver fast software based rendering of the full 3D rendering pipeline. It also provides transparent access to underlying hardware acceleration, if present.

This tutorial will present the details of the retained mode of Direct3D.


Motivation

In a previous tutorial, we have given an overview of the Direct3D API. We also briefly covered the different components of DirectX, the file format used to define 3D objects in Direct3D and also how to use COM objects through the C++ and C programming languages.

In this tutorial, we will cover one of the two modes of Direct3D. The mode we will be covering in this tutorial, is the retained mode. We will cover the other mode, namely the immediate mode in another tutorial.

For the retained mode, we will first give an overview of the retained mode. Then we will cover the steps to be followed to create a retained mode application, followed by the scene description of the 3D scene to be displayed. To concretise the steps of application creation, we will cover a sample application, which will also help in clarifying the different objects, methods and functions used while creating retained mode applications. to wrap up the tutorial, we will cover some of the objects that are provided by the retained mode, to get an idea of the things possible using the retained mode.

Introduction

As we mentioned in the overview of Direct3D ([7]), the retained mode is one of the two modes in which we can operate Direct3D. The other mode is the immediate mode, which will be covered in [6].

The retained mode is the higher-level mode of the two modes of Direct3D and provides a higher-level API to add 3D content to applications.

The retained mode is designed for manipulating 3D objects and 3D scenes. This is done by providing functions for creating and managing the scene and for manipulating the 3D objects to be displayed as a part of the scene.

A feature of the retained mode that is significant is that it uses the immediate mode, transparent to the application developer. The retained mode is built on top of the immediate mode and uses all the features of the immediate mode, to do its work, without exposing the low-level details to the application developer who is develping an application using the retained mode. The retained mode is also tightly coupled with DirectDraw, the API for fast 2D bitmap operations.

Features

A very important feature of the retained mode is that it provides a built-in geometry engine. This geometry engine manages the rendering pipeline and hence relieves the application of the mathematical calculations and equations, making the application simpler to develop. The engine supports features like texture mapping, light calculations, managing material properties, managing the ambient lighting conditions of the scene, the specular lighting of each object, the different shading models, like flat shading, gouraud shading and phong shading. The phong shading model is not supported in the present version of Direct3D. Retained mode also supports object display using points and as a wireframe. The engine also supports fixed path and keyframe animation. For more details on computer graphics, refer [3], [4], [9], [10], [11] and [12].

Support

The retained mode is a higher-level interface to the 3D functions provided by Direct3D and it provides support for 3D scene management and rendering. It provides very good support by maintaining the objects that are part of the scene, in an object database. It also manages the internal structures of the objects and manages the objects as they are manipulated in the scene, using the different transformations. Though scene management and object database management is a non-trivial task, the interface provided to the developer is simple and using this interface to manipulate the objects is quite easy.

Steps to Create an Application

After the introduction to the retained mode of Direct3D and its various features, let us now consider the steps to be followed to create an application using the retained mode.

To create a retained mode application, we need to create the Direct3D objects that are part of the scene and add them to the scene that is to be displayed. We then need to set the rendering state of the engine so that we can display the objects as desired. We then render the scene to display the scene.

The steps to create a retained mode application, are given below:

  1. Declare the variables required to store the different values of the retained mode application. The variables typically store pointer to a DirectDraw object, a Direct3D object, the scene, and other things
  2. Initialize Windows, to create the window, in which the scene is to be rendered
  3. After creating the window, we need to initialize and create the objects required to define the scene and the objects to be included as part of the scene
  4. As a step to initialize the retained mode, we first set the rendering quality of the rendering engine. The rendering quality will decide whether the objects will be displayed as points or wireframes or shaded, using flat shading or gouraud shading. After setting the rendering quality, we need to choose the device on which the scene has to be rendered. Choosing a device is important as this is the place where an appropriate hardware device is selected based on its capabilities. In this step, we decide upon various things, like selecting the proper colour model (ramp/RGB), whether to go for hardware acceleration, if available, etc
  5. Create the master frame and then the camera frame. The master frame defines the topmost frame in a scene and all other frames are placed underneath it, directly or indirectly. The camera frame describes the specifications for the camera to be used to view the scene
  6. Place the created scene in the master frame at the desired position. Positiong the camera will select the viewing parameters and the view to be used while displaying the scene
  7. Create a 2D clipping object, which will be attached to the viewport. The clipping object will help eliminate the parts of the object that lie outside the 2D projection plane and hence will not render thwm, increasing performance
  8. Create the device and the viewport. The viewport decides the 2D plane onto which the 3D data is projected. The viewport is finally mapped onto the window, that we created in a previous step
  9. Create the 3D objects to be added to the scene. The 3D objects after creation, have to be added to the scene, before they can be rendered. The objects added to a scene can either be created on-the-fly or can be loaded from an existing data file
  10. Create and place the lights in the scene
  11. Display the window
  12. After displaying the window, the application needs to go into an infinite loop, waiting for events to happen. In this step, if there are Windows events, they are processed by the window procedure provided by the application. If there are no events in the event queue, then the application has the choice of either taking no action ot rendering the next frame of the animation, if it exists, or any such action, that needs to be performed during the idle time of the application

Scene

After covering the steps to create a retained mode application and before considering a sample application, let us cover how a scene, to be rendered, has to be specified to the retained mode.

Description

A scene in retained mode is a hierarchy of frames, with the retained mode providing the basic frame object required to create this heirarchy. All frames, except the master frame have one and only one parent. A frame may or may not have child frame, below it. All frames have a position and an orientation. Only the master frame does not have a parent frame. The position and orientation of a frame is relative to the position and orientation of its parent frame. This relative positioning and orientation helps model the scene using hierarchic modeling, in which we can apply a transformation on one piece and it gets reflected on all the children as well. For a discussion on hierarchic modeling, refer [3].

As we mentioned, a scene definition consists of a hierarchy of frames. The master frame is the topmost parent, which does not have a parent. The camera to be used to set the viewing parameters, is also a frame and is attached to the master frame. We usually definr another frame, the world frame, below the master frame, for placing the objects and lights in the scene. This is done for easy manipulation of all the objects and lights in the scene, without affecting the camera and other such parameters. To add objects and lights to the scene, they are either added to their own frame, which in turn is added to the world frame. All objects and lights are placed in the world frame, directly or indirectly. Ambient light if any, is added to the master frame directly.

Creation

To create a scene, the following steps need to be followed:

  • Create master frame
  • Create camera and add it to the master frame
  • Create the ambient light and add it to the master frame
  • Create the worl frame and add it to the master frame
  • Load objects and create the lights and add then to the world frame

If required, objects and lights can have their own frames and these in turn are added to the scene, using the frames. Defining a frame for one single object or light gives us the advantage of manipulating only one object at a time, using its frame, without affecting the other objects in the scene.

Light Creation

To create a light with its own frame, the following steps have to be followed:

  • Create frame for the light
  • Create the light
  • Add the light to the frame
  • Set the frame orientation and position with respect to the parent frame
  • Add the framed light to the parent frame

Object Loading

To create an object with its own frame, the following steps have to be followed:

  • Create frame for the object
  • Create or load the object
  • Add the object to the frame
  • Set the frame orientation and position with respect to the parent frame
  • Add the framed object to the parent frame

Sample Scene

Consider the following scene description.

The scene consists of three objects, namely two spheres and one teapot object. It also has a directional light source, which uses the ramp model. The light is from the bottom right corner of the scene.

The scene, as it will appear when rendered, is shown in the figure 1.

scene2
Figure 1: Sample Scene

A diagrammatic representation of the frame hierarchy of the described scene is shown in figure 2.

hier
Figure 2: Sample Scene Hierarchy

In figure 2, the ambient light source is shown with dashed lines, to indicate that it is not present in the current scene. It is there, just to indicate the position of the ambient light, if added to the scene.

Sample Application

Let us now consider a sample application and go through its source code, to understand the steps required to create an application.

In this application, we will be going through the standard procedure to create a Direct3D retained mode application. The scene to be rendered, consists of a sphere and a light source. The sphere is loaded from a file (``sphere4.x'') and has a texture map (``hello.bmp'') associated with it. To do some work when the application is idle, we will rotate the sphere around its y axis.

The sphere, as it will look if displayed as a wireframe, is shown in figure 3.

sp4mesh
Figure 3: Wireframe Sphere

The image used for texture mapping is shown in figure 4.

hello
Figure 4: Texture Image

One position in the rotation of the sphere, during execution, are shown in figure 5.

texhello2
Figure 5: Position

Sample Application Source Code

We will now cover the source code for each of the steps described in a previous section.

Step 1: Define Global Variables

The source code for this step is shown in figure 6.

#define	INITGUID

LPDIRECT3DRM lpD3DRM;
LPDIRECTDRAWCLIPPER lpDDClipper;

struct taInf {
    LPDIRECT3DRMDEVICE dev;
    LPDIRECT3DRMVIEWPORT view;
    LPDIRECT3DRMFRAME scene, camera;
    GUID DriverGUID[MAX_DRIVERS];
    char DriverName[MAX_DRIVERS][50];
    int NumDrivers, CurrDriver;
    BOOL bQuit, bInitialized, bMinimized;
    int BPP;
} aInf;

Figure 6: Step 1 Source Code

In this step, we have put all the required variables into one structure, for convenience, during initialization. Some of the variables used are:

  • dev - stores pointer to the Direct3DRM device object selected
  • view - stores pointer to the Direc3DRM viewport object
  • DriverGUID - this array helps store a list of devices connected to the machine. From this list of devices, we will choose the one which best suits our needs
  • BPP - stores the number of bits per pixel used and decides the colour depth. This information is used to decide the colour model used
  • CurrDriver - indicates the device used, from the list of devices connected

Step 2: Setup Windows

The source code for this step is shown in figure 7.

memset(&aInf, 0, sizeof(aInf));
RegisterClass(&wc)
win = CreateWindow("Hello", "Hello World -- D3DRM Style",
    WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
    500, 500, NULL, NULL, hInstance, NULL);
Figure 7: Step 2 Source Code

In this step, we create the Window on which the scene is to be rendered. (For more details on creation of Windows using SDK, refer [8].)

Step 3: Setup Direct3D

The source code for this step is shown in figure 8.

// get bits per pixel /depth
hdc = GetDC(win);
aInf.BPP = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(win, hdc);
// enumerate device drivers
EnumDrivers(win);
// create Direct3D object
lpD3DRM = NULL;
Direct3DRMCreate(&lpD3DRM);
Figure 8: Step 3 Source Code

In this step,

  • We first query the Windows system to get the bits-per-pixel information
  • Then, we enumerate the drivers attached and from the enumerated drivers, select the one that suits our requirements best
  • After enumerating the devices, we create the Direct3DRM object that will be used to create and manipulate the scene

The enumeration code is defined in the EnumDrivers function. This function has been defined to modularise the code. The source code to enumerate the drivers is shown in figure 9.

LPDIRECTDRAW lpDD;
LPDIRECT3D lpD3D;
HRESULT rval;

// Create a DirectDraw object and query for the Direct3D interface 
// to use to enumerate the drivers
DirectDrawCreate(NULL, &lpDD, NULL);
lpDD->QueryInterface(IID_IDirect3D, (void**) &lpD3D);

// Enumerate the drivers
lpD3D->EnumDevices(enumDeviceFunc, &aInf.CurrDriver);
	
lpD3D->Release();
lpDD->Release();
Figure 9: Enumeration Source Code

  • Before enumerating the drivers, we create a DirectDrawSurface using the DirectDrawCreate method of the DirectDraw object
  • We then query the DirectDraw object and find if it supports the Direct3D object
  • If Direct3D is supported, we enumerate over the Direct3D object to find the drivers
  • Selection of the appropriate driver is done in the enumDeviceFunc callback function
  • After using the DirectDraw and Direc3D objects, we release them using the Release method

Step 4: Create Master Frame and Camera

The source code for this step is shown in figure 10.

lpD3DRM->CreateFrame(NULL, &aInf.scene);
lpD3DRM->CreateFrame(aInf.scene, &aInf.camera);
aInf.camera->SetPosition(aInf.scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0));
Figure 10: Step 4 Source Code

In this step

  • After creating the Direc3DRM object, we create the master frame and the camera frame using the CreateFrame method
  • The camera frame is created as a child of the master frame and is placed at the desired position using the SetPosition method

Step 5: Create Clipper

The source code for this step is shown in figure 11.

DirectDrawCreateClipper(0, &lpDDClipper, NULL);
lpDDClipper->SetHWnd(0, win);
Figure 11: Step 5 Source Code

In this step, after creating the master frame, we create the clipper using the DirectDrawCreateClipper method and attach it to the Window using the SetHWnd function

Step 6: Create Direc3DRM Device

The source code for this step is shown in figure 12.

GetClientRect(win, &rc);
CreateDevAndView(lpDDClipper, aInf.CurrDriver, rc.right, rc.bottom);
Figure 12: Step 6 Source Code

The device and viewport creation is defined in the CreateDevAndView function. This function has been defined to modularise the code. In this step, we create the device and the viewport. The device is created by using the CreateDeviceFromClipper method, as shown in figure 13.

lpD3DRM->CreateDeviceFromClipper(lpDDClipper,
    &aInf.DriverGUID[driver], width, height, &aInf.dev);
Figure 13: Creating the Device

The viewport is created using the CreateViewport method, as shown in figure 14.

width = aInf.dev->GetWidth(); height = aInf.dev->GetHeight();
lpD3DRM->CreateViewport(aInf.dev,
    aInf.camera, 0, 0, width, height, &aInf.view);
aInf.view->SetBack(D3DVAL(5000.0));
Figure 14: Viewport Creation

After creating the viewport, we set the back clipping plane of the viewing frustum to the desired value. We then set the rendering quality and other parameters, like fill mode, lighting state, as shown in figure 15.

aInf.dev->SetShades(32);
lpD3DRM->SetDefaultTextureColors(64);
lpD3DRM->SetDefaultTextureShades(32);
Figure 15: Rendering Parameters

Step 7: Define Scene

The source code for this step is shown in figure 16.

DefineScene(aInf.dev, aInf.view, aInf.scene, aInf.camera);
Figure 16: Step 7 Source Code

After creating the device and the viewport, we create the scene to be rendered. To define a scene, we first create the world frame, using the CreateFrame method. We then create a frame for the ambient light to be added to the scene, as shown in figure 17.

LPDIRECT3DRMFRAME lpLightFrame, lpWorldFrame;
LPDIRECT3DRMLIGHT lpLight1, lpLight2;
LPDIRECT3DRMTEXTURE lpTex;
LPDIRECT3DRMWRAP lpWrap;
LPDIRECT3DRMMESHBUILDER lpMesh;

// create frame
lpD3DRM->CreateFrame(lpScene, &lpLightFrame);
lpD3DRM->CreateFrame(lpScene, &lpWorldFrame);

MakeScnLights(lpScene, lpCamera, lpLightFrame, &lpLight1, &lpLight2);
SetScnPositions(lpScene, lpCamera, lpLightFrame, lpWorldFrame);
MakeScnMesh(&lpMesh);
MakeScnWrap(lpMesh, &lpWrap);
AddScnTexture(lpMesh, &lpTex);

lpWorldFrame->AddVisual((LPDIRECT3DRMVISUAL) lpMesh);

lpLightFrame->Release();
lpWorldFrame->Release();
lpMesh->Release();
lpLight1->Release();
lpLight2->Release();
lpTex->Release();
lpWrap->Release();
Figure 17: Creating the Scene

After creating the frames, we create the lights to be used in the scene, as shown in figure 18.

lpD3DRM->CreateLightRGB(D3DRMLIGHT_DIRECTIONAL,
    D3DVAL(0.9), D3DVAL(0.9), D3DVAL(0.9), lplpLight1);
lpLightFrame->AddLight(*lplpLight1);

lpD3DRM->CreateLightRGB(D3DRMLIGHT_AMBIENT,
    D3DVAL(0.1), D3DVAL(0.1), D3DVAL(0.1), lplpLight2);
lpScene->AddLight(*lplpLight2);
Figure 18: Creating the Lights

Here, we create two light sources, one being a directional light source amd the other being the ambient light source. The light sources are created using the CreateLightRGB method and added to the frame using the AddLight method. The directional light source is added to the world frame, while the ambient light source is added to the master frame.

After creating the lights, we set the positions of the different frames, like the world frame, the camera frame, as shown in figure 19. A frame is positioned and oriented with respect to its parent, using the SetPosition and the SetOrientation methods respectively.

lpLightFrame1->SetPosition(lpScene,
    D3DVAL(2), D3DVAL(0.0), D3DVAL(22));

lpCamera->SetPosition(lpScene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0));
lpCamera->SetOrientation(lpScene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1),
    D3DVAL(0.0), D3DVAL(1), D3DVAL(0.0));

lpWorldFrame->SetPosition(lpScene, D3DVAL(0.0), D3DVAL(0.0),
    D3DVAL(15));
lpWorldFrame->SetOrientation(lpScene, D3DVAL(0.0), D3DVAL(0.0),
    D3DVAL(1), D3DVAL(0.0), D3DVAL(1), D3DVAL(0.0));
lpWorldFrame->SetRotation(lpScene, D3DVAL(0.0), D3DVAL(0.1),
    D3DVAL(0.0), D3DVAL(0.05));
Figure 19: Frame Placement

After positioning the frames, we need to create the object, namely the sphere, as shown in figure 20.

lpD3DRM->CreateMeshBuilder(&lpMesh);
lpMesh->Load("sphere4.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL);
lpMesh->Scale(D3DVAL(2), D3DVAL(2), D3DVAL(2));
lpMesh->SetColorRGB(D3DVAL(1), D3DVAL(1), D3DVAL(1));
Figure 20: Loading the Sphere

To load the sphere, we first need to create the mesh object to hold the sphere data, using the CreateMeshBuilder method. We then use the Load method, to load the sphere data from the file ``sphere4.x''. After loading the data, we can transform the objects as desired. We can also set the various parameters of the object. Here we set the colour of the object using the SetColorRGB method.

After loading the object, we need to specify the texture mapping function to be used while applying the texture to the object, as shown in figure 21. The CreateWrap method is used to specify the texture wrapping to be used for texture mapping.

D3DVALUE miny, maxy, height;
D3DRMBOX box;
lpMesh->GetBox(&box);
maxy = box.max.y; miny = box.min.y; height = maxy - miny;
lpD3DRM->CreateWrap(D3DRMWRAP_CYLINDER, NULL,
    D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
    D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
    D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
    D3DVAL(0.0), D3DDivide(miny, height),
    D3DVAL(1.0), D3DDivide(-D3DVAL(1.0), height), &lpWrap);
Figure 21: Texture Wrapping Function

After creating the wrapping function, we need to apply it to the selected object using the Apply method, as shown in figure 22.

D3DVALUE miny, maxy, height;
D3DRMBOX box;
lpMesh->GetBox(&box);
maxy = box.max.y; miny = box.min.y; height = maxy - miny;
lpD3DRM->CreateWrap(D3DRMWRAP_CYLINDER, NULL,
    D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
    D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
    D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0),
    D3DVAL(0.0), D3DDivide(miny, height),
    D3DVAL(1.0), D3DDivide(-D3DVAL(1.0), height), &lpWrap);
Figure 22: Applying Texture Wrap

After applying the texture wrap, we need to load the image to be used as the texture. A texture image can be loaded using the LoadTexture method. A texture is a 2D image, as either in the .bmp or the .ppm file formats. After loading the texture, it is applied to the object using the SetTexture method as shown in figure 23.

lpD3DRM->LoadTexture("hello.bmp", &lpTex);
lpMesh->SetTexture(lpTex);
Figure 23: Setting the Texture

After loading the object, it is added to the frame using the AddVisual method.

Step 8: Display Window

The source code for this step is shown in figure 24.

ShowWindow(win, cmdshow);
UpdateWindow(win);
Figure 24: Step 8 Source Code

After creating and initializing the different Direct3D and Windows objects, we display the window using the ShowWindow function, as shown in figure 24.

Step 9: Render Loop

The source code for this step is shown in figure 25.

HRESULT rval;
aInf.scene->Move(D3DVAL(1.0));
aInf.view->Clear();
aInf.view->Render(aInf.scene);
aInf.dev->Update();
Figure 25: Step 9 Source Code

After loading the scene and rendering it for the first time, we need to go into an infinite loop, waiting for events. Events are processed by the window procedure as they happen. If there are no events to be processed, the application will be idle, during which time, we will rotate the object by a fixed amount and re-render the scene, as shown in figure 25.

The complete source of the application in C++, is presented in appendix A.

For another sample, refer [5].

Retained Mode Objects

The retained mode provides some standard objects with well defined behaviour. These objects help in reducing the amount of work required to be done by the application and hence help in reducing application development time. We will cover some of the object provided by the retained mode in the following subsections.

Direct3DRMDevice

Represents a visual display destination. The behaviour of the renderer depends on the type of the output device used for rendering. Though only one device is used, multiple viewports on one device can be defined. On the device, we can set parameters like rendering quality and the colour model used for rendering.

Direct3DRMFace

Represents one single face in a mesh. A mesh object, represented by a Direct3DRMMesh object, is a collection of these face objects.

Direct3DRMFrame

Represents a frame in the scene. It can be used in many ways. The primary usage is for placing various objects and lights in a scene and manipulating them. A scene as we mentioned earlier, is a hierarchy of frames. One frame can contain many objects, lights and other frames, but each frame has atmost one parent.

Direct3DRMLight

Represents a light source in a scene. A light source on creation, has to be added to a frame. A light source can be any one of the following types:

Ambient
- the amount of light present at each point in the scene
Directional
- light rays have a direction and are parallel. Light is considered to be placed at an infinite distance. Can be used to model a Sun-like light source
Parallel Point
- similar to Directional light, but light is placed at specified point
Point
- light is placed at specified point. Light emits equally in all directions
Spotlight
- light is placed at specified point. Light is emitted as a cone, with the apex being at the specified point

Direct3DRMMesh

Represents a set of polygonal faces, making up the mesh object to be displayed. It defines a set of vertices and a set of faces using the defined set of vertices.

Direct3DRMMeshBuilder

Built on top of the Direct3DRMMesh object. It provides a convenient way to access the vertices and faces of the mesh object. It provides methods to load a mesh and also for transforming the mesh by translation, scaling and rotation.

Direct3DRMMeshMaterial

Represents the material properties of an object, which defines how a surface reflects the incident light. This object is used to decide two components of the light, namely the emmissive properties and the specular properties. The brightness of the object on receiving light is determined by a value called the power setting, which determines the sharpness of the reflected highlights. A value of less than 5 for the power setting gives a metallic finish to the object, while a value geater than or equal to 5 gives a plastic finish to the object.

Direct3DRMTexture

Used for texture mapping and is an interface to the DirectDrawSurface object. The texture used can be a 2D image, either in the .bmp format or the .ppm format. It should be kept in mind that the image data in a bitmap (.bmp) file is upside down, while a .ppm file is correct side up. This object just manages the texture to be used for texture mapping. To actually do texture mapping, the Direct3DRMWrap object has to be used, to specify the wrapping function, alongwith this object.

Direct3DRMViewport

Defines how the 3D scene is rendered on a 2D window. It defines a rectangular area on the device for rendering the objects in the scene. To do this, it supports a camera, a viewing frustum and the transformations. It additionally supports picking of objects.

Camera
- defines the viewing position and the viewing direction. The camera renders the scene visible along the positive z axis and up direction of the positive y axis
Viewing Frustum
- defines a 3D volume in a scene, positioned relative to the viewport camera. Only objects in the viewing frustum are visible.
Transformations
- the viewport supports projection transformations, which consist of projections like parallel and perspective and also supports scaling and translation of the viewport and its parameters
Picking
- this feature allows object picking in a scene, given the 2D coordinates. To pick an object, the Pick method of IDirect3DRMViewport object is used. This method either returns the nearest object, if only one object lies at the specified position or a depth sorted list of objects, if there are many objects at the specified position

Direct3DRMWrap

Used to calculate the texture coordinates for an object. To create a wrapping function for an object, we need to specify the type of wrapping used, the reference frame and origin, the direction vector, the up vector, a pair of scaling factors and the origin for the texture coordinates. The wrapping function determines how the rasterizer module interprets the texture coordinates.

The different types of wrapping functions that can be specifie are:

Flat
- 2D image is mapped to a 2D object
Cylindrical
- the object is placed inside a hollow cylinder with the texture on the innder side of the cylinder. The cylinder is then collapsed onto the object
Spherical
- the object is placed inside a hollow sphere with the texture on the innder side of the sphere. The sphere is then collapsed onto the object
Chrome
- also called environment mapping. It is similar to spherical mapping. Here the reflected ray of light is used to select the texture to be specified at a point on the object

Note

For a description of all the objects provided by the retained mode, refer [1] and [2].

Sample Images

To conclude this tutorial on the retained mode, we present some images in figures 26, 27 and 28 from a few samples, to illustrate a few visual aspects created using retained mode applications.

multi
Figure 26: Sample Image #1

point
Figure 27: Sample Image #2

teapot2
Figure 28: Sample Image #3

Appendix A

In this section, we present the complete source code, using C++ and COM, of the sample application. This sample application was used for illustration purposes, to explain the retained mode in a previous section.

Direct3D Retained Mode Sample Application Source Code

Summary

In this tutorial, we have seen that the retained mode of Direct3D is a higher-level mode and provides a higher-level interface to the 3D requirements of an application. It is built on top of the immediate mode and provides a rendering engine, which uses standard algorithms for the 3D operations in a 3D graphics application.

We covered the various features of the retained mode and the kind of support it provides for application creation. We also covered the steps required to create an application using the retained mode and finally had a look at the different objects provided by the retained mode for application development.

References

1
Microsoft Corporation. DirectX SDK (ver 3.0, 5.0) Reference. Microsoft Corporation, 1996-97.

2
Microsoft Corporation. Direct3D Reference Manual. Microsoft Corporation, 1997. Visual Studio Help.

3
Foley and Van Damm. Introduction to Computer Graphics. Addison Wesley, 1994.

4
Donald Hearn and Pauline Baker. Computer Graphics. Prentice Hall of India, 2nd edition, 1994.

5
David Joffe. Guide to Programming Games with DirectX : Chapter 4 : Simple Direct3D Retained Mode Sample. DirectX Developer Pages (www.oocities.org/SiliconValley/Way/8390/dj4.html), 1997.

6
Bipin Patwardhan. Direct3D Immediate Mode. National Centre for Software Technology, Mumbai, India, Aug-Sep 1997. Intel Developers Conference, Aug-Sep 97.

7
Bipin Patwardhan. Overview of Direct3D. National Centre for Software Technology, Mumbai, India, Aug-Sep 1997. Intel Developers Conference, Aug-Sep 97.

8
Charles Petzold. Windows 95 Programming. Microsoft Press, 1st edition, 1996.

9
David Rogers. Procedural Elements for Computer Graphics. McGraw-Hill Book Company, 1st edition, 1985.

10
David Rogers. Mathematical Elements for Computer Graphics. McGraw-Hill Book Company, 2nd edition, 1990.

11
Alan Watt. Fundamentals of Three Dimensional Computer Graphics. Addison Wesley, 1989.

12
Alan Watt. 3D Computer Graphics. Addison Wesley, 2nd edition, 1993.


Bipin Patwardhan
Fri Jan 2 12:22:09 GMT 1998
®1998 Adam Perer. All rights reserved.
This site was designed by
Adam Perer, head of The DirectX Developer Page
This site is hosted by
Geocities