Direct3D RM

Home | Up | Search | X-Zone News | Services | Book Support | Links | Feedback | Smalltalk MT | The Scrapyard | Technical Articles


X-Zone's DirectX FAQ
Direct3D Retained Mode

Special thanks to Michael Lundberg for contributing the contents for this section of the FAQ.

Direct3D Retained Mode

How do I construct a mesh if I have all the necessary information on its vertices?

Can I map my texture on a surface without using IDirect3DRMWrap?

If I create an animated character in 3D Studio, how do I use it in my program?

How do I make use of triple buffering in my D3DRM full screen application?

Can I use single/multiple pass multi-texture in D3DRM?

How can I use mipmapping in D3DRM?

What about anti-aliasing in D3DRM?

Q. How do I construct a mesh if I have all the necessary information on its vertices?

There are two ways to construct a 3D object by giving detailed info on its vertices: use IDirect3DRMMesh or IDirect3DRMMeshBuilder. Both of them support run-time manipulate of 3D objects. In the new IDirect3DRMMeshBuilder3, besides the old mesh and vertex functions, you can also use CreateSubMesh() and DeleteSubMesh() to group meshes into "sub-meshes".

 If you want to use IDirect3DRMMesh to create the 3D object, you need to:

  1. Have all the necessary information on all the vertices.
  2. Provide an array, which indicates the vertex order of the mesh.
  3. Provide an array, which contains all the vertices' data.
  4. Have a valid pointer to IDirect3DRM.

Let's look at a simple example on creating a square face with 4 vertices:

We have 4 vertices. Their order is 0, 1, 2, and 3. Note that the vertices are arranged in clockwise order if we look at the face from the look direction.

D3DRMGROUPINDEX groupid; // mesh group id
D3DRMVERTEX v[4];              // 4 vertices for the face
unsigned fData[]={0, 1, 2, 3}; // vertices index

hRes=lpD3DRM->CreateMesh(&my_Plate); // create a mesh

if (FAILED(hRes)) // fail to create a mesh?


/*** Assign data for all of the vertices****/

v[0].position.x=D3DVAL(-32); v[0].position.y=D3DVAL(0);
v[0].position.z=D3DVAL(32); v[0].normal.dvX=D3DVAL(0);
v[0].normal.dvY=D3DVAL(1); v[0].normal.dvZ=D3DVAL(0);

v[1].position.x=D3DVAL(32); v[1].position.y=D3DVAL(0);
v[1].position.z=D3DVAL(32); v[1].normal.dvX=D3DVAL(0);
v[1].normal.dvY=D3DVAL(1); v[1].normal.dvZ=D3DVAL(0);

v[2].position.x=D3DVAL(32); v[2].position.y=D3DVAL(0);
v[2].position.z=D3DVAL(-32); v[2].normal.dvX=D3DVAL(0);
v[2].normal.dvY=D3DVAL(1); v[2].normal.dvZ=D3DVAL(0);

v[3].position.x=D3DVAL(-32); v[3].position.y=D3DVAL(0);
v[3].position.z=D3DVAL(-32); v[3].normal.dvX=D3DVAL(0);
v[3].normal.dvY=D3DVAL(1); v[3].normal.dvZ=D3DVAL(0);

// create group and return the group_id

my_Plate->AddGroup(4, 1, 4, fData, &groupid);

/*** Once you create group, you can use Group to do things like set texture, and set material and color..etc , it is a good way to optimize the performance for RM ***/

my_Plate->SetGroupQuality(groupid, D3DRMRENDER_FLAT);

/** Now set all the vertices data for the face**/

my_Plate->SetVertices(groupid, 0, 4, v);

/** Yahoo!!. That is all for a face**/
/** all we need to do to make it visible is adding the mesh to a frame **/
/** Assume you have a scene frame already, lpScene**/


As stated in the DX SDK Docs, you can use AddVertex, AddFace and AddFaces to manipulate a Meshbuilder object.

Back to the Top    Back to Main Index

Q. Can I map my texture on a surface without using IDirect3DRMWrap?

If you created the 3d mesh by supplying your own vertices, you can control the texture appearance. The tu and tv in D3DRMVERTEX structure is for texture mapping coordination. tu is for specifying how many times you want to texture tile along the U direction and tv is for V direction. Look at the above example, set:

v[0].tu=0; v[0].tv=0;
v[1].tu=1; v[1].tv=0;
v[2].tu=1; v[2].tv=1;
v[3].tu=0; v[3].tv=1;

Then use SetGroupTexture() to set the texture for the mesh. If you change the v[1].tu and v[2].tu to 2, you will see the texture is tile along the U direction twice.

Back to the Top    Back to Main Index

Q. If I create an animated character in 3D Studio, how do I use it in my program?

It's not difficult to load an animated 3d object in Direct3D RM. Using IDirect3DRMAnimationSet2 can easily load a pre-build animation into scene.

To load an animated object, you need to:

1.       Create your animation object in 3D studio or other 3D modeling/animating packages.

2.       Export/convert your animation object/scene to a .X file.

3.       Create an IDirect3DRMFrame3 for the AnimationSet.

4.       Create an AnimationSet2,

5.       Use IDirect3DRMAnimationSet2::Load() to load the animation file.

6.       Use IDirect3DRMAnimationSet2::SetTime() to set the time to 0.

7.       Create a Callback function, and add it to the Frame as a movecallback function

8.       You can now control the animation's playback by using the IDirect3DRMAnimationSet2::SetTime( ) inside the animation callback function.

 Some high-end 3D modeling/animation packages come with a DirectX exporter, for example, SoftImage3D. You can directly export your animation work to a .X file by using these exporters. However, if the software you are using do not have a DirectX exporter, you will need to output your work to 3DS format, then use a program called "conv3ds" (comes with DirectX SDK) to convert the 3DS file to .X file. When using "conv3ds" to convert the animation, you should choose the "-A" option. (Note: it's a UPPER case 'A').

If your 3D software cannot output 3ds and DirectX file, you still can use some 3rd party file converter to do the job, for example, PolyTran 2.0.

Back to the Top    Back to Main Index

Q. How do I make use of triple buffering in my D3DRM full screen application?

There is a very detailed explanation in DirectX SDK document in regarding triple buffering. Similar to double buffering applications, you will need (assume you are using HAL):

1.       Set the backbuffer count to 2 when creating the primary surface,

2.       Get a backbuffer pointer from this surfaces chain by using GetAttachedSurface.

3.       Create a Z-buffer.

4.       Attach the z-buffer to the backbuffer.

5.       Create IDirect3DDevice2.

6.       Create IDirect3DRMDevice2.

7.       Set the buffer count for the D3DRMDevice2 to 3 by using SetBufferCount .

8.       Done!

 As you can see, only the 1st and 7th step are the different from double buffering. In double buffering, we set the backbuffer count to 1, and set buffercount to 2.

Back to the Top    Back to Main Index

Q. Can I use single/multiple pass multi-texture in D3DRM?

No, you can't.

Back to the Top    Back to Main Index

Q. How can I use mipmapping in D3DRM?

Use IDirect3DRMDevice3::SetTextureQuality, set the value to D3DRMTEXTURE_MIPLINEAR or D3DRMTEXTURE_LINEARMIPLINEAR (for tri-linear filtering). After loading your texture, use GenerateMipMap(0) to create Mipmap, then set the texture to your mesh.

Back to the Top    Back to Main Index

Q. What about anti-aliasing in D3DRM?

The D3DRMDevice does not support anti-aliasing. If you want to use anti-aliasing in D3DRM, you need to obtain an IDirect3DDevice2 pointer, then use IDirect3DDevice2::SetRenderState to enable anti-aliasing.

 (Assume you already have a pointer to IDirect3DRMDevice2 lpDevice2)




if (FAILED(hRes))



//enable anti-aliasing

if (FAILED(hRes))


Note that not all the 3D card support this feature under D3D, the above code is tested on i740, Riva 128/ZX and Riva TNT cards. And on i740 cards, you need to disable alpha blending before you enable anti-aliasing.

Back to the Top    Back to Main Index

This site, created by DirectX MVP Robert Dunlop and aided by the work of other volunteers, provides a free on-line resource for DirectX programmers.

Special thanks to WWW.MVPS.ORG, for providing a permanent home for this site.

Visitors Since 1/1/2000: Hit Counter
Last updated: 07/26/05.