Over here I’ll shove in some basics, like coordinate systems, world and object coordinate systems, etc. For now I’ll assume you’re at least a little familiar with 3D programming. Blah blah blah, differences between immediate and retained mode, etc etc.

Devices

Direct3D interfaces with the surface it is rendering to (e.g. screen memory, system memory) using an IDirect3DRMDevice object. More than one type of rendering device can exist and a specific rendering device must be chosen for a scene. For example, there is normally a device for RGB rendering and a device for Mono rendering (these names refer to the lighting model used for rendering. Mono means that only white lights can exist in the scene, while RGB supports colored lights, and is thus slower). Additional devices may be installed that make use of 3D hardware acceleration. It is possible to iterate through the installed D3D devices by enumarating through them (EnumDevices). It is possible to have two different devices rendering to the same surface.

Viewports

The IDirect3DRMViewport object is used to keep track of how our 3D scene is rendered onto the device. It is possible to have multiple viewports per device, and it is also possible to have a viewport rendering to more than one device. The viewport object keeps track of the camera, front and back clipping fields, field of view etc.

Frames

A frame> in Direct3D is basically used to store an object’s position and orientation information, relative to a given frame of reference, which is where the term frame comes from. Frames are positioned relative to other frames, or to the world coordinates. Frames are used to store the positions of objects in the scene as well as other things like lights. OK, so I’m explaining it badly. It’s late, I’m tired, I’ll revise it soon. To add an object to the scene we have to attach the object to a frame. The object is called a visual in Direct3D, since it represents what the user sees. So, a visual has no meaningful position or orientation information itself, but when attached to a frame, it is transformed when rendered according to the transformation information in the frame. Multiple frames may use the same visual. This can save a lot of time and memory in a situation like, for example, a forest or a small fleet of spacecraft, where you have a bunch of objects that look exactly the same but all exist in different positions and orientations.

Here is a crummy ASCII diagram of a single visual attached to two frames which are at different positions:

If both of these frames were attached to the scene frame, then our scene would have 2 cubes in it; one at (21, 3, 4) and the other at (-12, 10, -6).

The Direct3D RM Sample

Setting up global variables

Before we start we’ll need a few global variables.

Note that we need both a DirectDraw object and a Direct3D object to create a Direct3D application. This is because Direct3D works in conjunction with DirectDraw. As before, we need a primary and a back surface for our double-buffering, and a clipper to handle window-clipping in windowed mode. The palette object is still not discusses in this tutorial (yet). We have objects for the device and viewport, and we have frame objects to keep track of the scene and the scene’s camera. Also, we have a frame that is used for the object we’ll have in this scene.

Here is a routine just to initially flatten these globals:

From ‘Initializing the DirectDraw system’ to ‘Creating the clipper’

These steps all proceed exactly as in the DirectDraw sample, with the exception of the CreateSurface function, where the back surface has to created with the DDSCAPS_3DDEVICE, since it will be used for 3d rendering:

Creating the Direct3D Retained Mode object

Now we need to create an IDirect3DRM object. This is achieved, quite simply, by calling the Direct3DRMCreate function.

Creating the device for rendering

We create the device object from the back surface, since this surface is the one we will render to.

Creating the viewport

We do a bit more than just create the viewport here. We create the scene object and the camera object, as well as set the ambient light for the scene, and create a directional light.

Putting it all together

Here is the tail-end of the app’s InitInstance function:

Restoring lost surfaces

Same as the DirectDraw sample:

The Rendering loop

Same as the DirectDraw sample:

The HeartBeat function