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:
- Have all the necessary information on all the vertices.
- Provide an array, which indicates the vertex order of the mesh.
- Provide an array, which contains all the vertices' data.
- 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.
LPDIRECT3DRMMESH my_Plate;
HRESULT hRes;
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?
return;
/*** 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**/
lpScene->AddVisual((LPDIRECT3DRMMESH)my_Plate);
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)
LPDIRECT3DDEVICE2 lpD3DDevice2=NULL;
HRESULT hRes;
hRes=lpDevice2->GetDirect3DDevice2(&lpD3DDevice2);
if (FAILED(hRes))
return;
hRes=lpD3DDevice2->SetRenderState(D3DRENDERSTATE_ANTIALIAS,
D3DANTIALIAS_SORTINDEPENDENT);
//enable anti-aliasing
if (FAILED(hRes))
return;
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