************************************
***                              ***
***                              ***
*** Direct3D Retained Mode Notes ***
*** DirectX 5                    ***
***                              ***
***                              ***
************************************

Last updated  June 24, 1997 - DirectX 5 Release

Interface Issues
================

With the exception of the IDirect3DRM2 interface, all
interfaces now inherit from the previous interface.
I.e. IDirect3DRMDevice2 inherits from IDirect3DRMDevice.  This means
that an application can legally (in C++) pass a IDirect3DRMDevice2
pointer into a function that is expecting an IDirect3DRMDevice
interface.  In C it is now legal to cast an IDirect3DRMDevice2 to a
IDirect3DRMDevice.

New Interfaces
==============

The COM model that Direct3D Retained Mode uses specifies that
additional functionality is provided by providing new interfaces.
This release of D3DRM provides the following new interfaces:

IDirect3DRM2
IDirect3DRMDevice2
IDirect3DRMFrame2
IDirect3DRMTexture2
IDirect3DRMMeshBuilder2
IDirect3DRMInterpolator
IDirect3DRMProgressiveMesh


The changes (and additional functionality) are detailed here.


IDirect3DRM2
============

New Members
-----------
This interface adds a new member function CreateProgressiveMesh().
See the section on progressive meshes for information about this new
object.

New Functionality
-----------------

Device behaviour

The new IDirect3DRM2 interface creates devices based on the new
functionality provided by the Immediate Mode IDirect3D2 interface.
Immediate Mode devices can be created in two ways.

1) By calling QueryInterface from an IDirectDrawSurface.  In this case
   the IDirect3DDevice cannot be queried for the new IDirect3DDevice2
   interface.

2) By caling IDirect3D2::CreateDevice.  This method creates an
   immediate mode device and returns a pointer to an IDirect3DDevice2
   interface. This interface can then be queried for an IDirect3DDevice
   interface if required.
   The difference with an immediate mode device created in this
   fashion is that it cannot be queried for an IDirectDrawSurface as the
   interface was not queried from an IDirectDrawSurface in the first
   place (as in case 1).
   Therefore, the immediate mode device returned by the retained mode
   IDirect3DRMDevice::GetDirect3DDevice() member cannot be queried for the
   underlying IDirectDrawSurface in this case.

The original IDirect3DRM interface creates devices using method 1 and
the IDirect3DRM2 interface creates devices using method 2.  In each
case, both the original and new retained mode device interfaces are
available.

Texture behaviour
-----------------
Textures loaded from bmp files in the IDirect3DRM interface were
loaded upside-down.  This has been corrected in the IDirect3DRM2
interface.


IDirect3DRMDevice2
==================

New members
-----------
SetRenderMode() and GetRenderMode() allow the application to specify
if true alpha blending is to be used (if available) as opposed to
stippled alpha.  This functionality depends on the new immediate mode
device functionality, therefore the device must be created by the
IDirect3DRM2 interface.


IDirect3DRMTexture2
===================

New members
-----------
GenerateMIPMap() generates a mipmap stack for the current texture and
also generates filtered images.  This is provided for applications
that do not want to provide their own MIP levels.

New behaviour
-------------
The InitFromXXX() members when initialized from bmp files load the
images the correct way up.

Textures now support alpha, but in order to gain alpha functionality they
must be created from the IDirect3DRM2 interface.  This is so old behavior
is maintained for old applications using the IDirect3DRM.


IDirect3DRMMeshBuilder2
=======================

New behaviour
-------------
The GenerateNormals2() takes an extra argument for a crease
angle.  The flags field specifies whether this should be used or not.


IDirect3DRMFrame2
=================

New members
-----------

GetMaterial() and SetMaterial() allow the application to specify a
material to be inherited down the frame hierarchy.

GetBox(), SetBox(), GetBoxEnable() and SetBoxEnable() allow the
application to provide a bounding box for hierarchy culling.
You *must* call SetBox() before SetBoxEnable().

GetHierarchyBox() allows an application to obtain the bounding box for
an entire hierarchy.

GetAxes() and SetAxes() allow the application to specify which vectors
are aligned with the direction and up vectors supplied to
SetOrientation().
The defaults are dir=(0, 0, 1) and up=(0, 1, 0).

GetInheritAxes() and SetInheritAxes() allow the application to specify
if a frame is to inherit it's parents axes.  The default is to
inherit.

RayPick() allows an application to perform true ray picking.  The
member traverses the hierarchy starting at the frame and calculates
intersections with any visuals with the ray specified by dvPosition
and dvDirection in the coordinate space specifed by the frame given as
a reference.

New behaviour
-------------
IDirect3DRMFrame::GetOrientation() incorrectly obtains an orientation if the
reference frame is not the parent frame.  In order to get the correct result
use the IDirect3DRMFrame2::GetOrientation() method.


New Flags for Viewports
=======================

It is now possible to use a right handed coordinate space by
specifying D3DRMPROJECT_RIGHTHANDPERSPECTIVE or
D3DRMPROJECT_RIGHTHANDORTHOGRAPHIC to the
IDirect3DRMViewport::SetProjection member.


Interpolators
=============

Interpolators provide a way of storing and playing back object actions
with automatic in-betweening of parameter values.  Their functionality
is a superset of the Animation interface and has been generalized to
cover several D3DRM object types.  Please see the online documentation
for a full treatment on interpolators, and also the "morph" sample.

Progressive Meshes
==================

Progressive Meshes are a new type of visual that allow progressive
rendering.  The mesh can be set to any level of face or vertex
detail.  In addition, these visuals can be rendered before all the
data has been loaded.  In order to facilitate this, the
IDirect3DRMProgressiveMesh::Load() member accepts a new load option:
D3DRMLOAD_ASYNCHRONOUS.  The application can then provide events to
the progressive mesh object that will be signalled at various stages
of the load process.

Loading from a URL
==================
When loading a mesh from a URL, if no texture callback is provided,
Retained Mode will attempt to load the texture via URL.  The sematics
for generating the URL for a texture are the same as for a standard
web document.  I.e. if the texture does not contain "http://" then the
path is assumed to be relative from where the original object was
loaded.


Please see the online documentation for a full treatment on
progressive meshes.

(For more detailed technical information, see
http://www.research.microsoft.com/research/graphics/hoppe/siggraph96pm/paper.html).

The "viewer" sample has been enhanced to load progressive meshes
asynchronously.

Several progressive meshes have been provided on the SDK in
\dxsdk\sdk\media.

A preliminary conversion tool has been provided in
\dxsdk\sdk\bin\pmesh.  The convpm.bat batch file will convert a
DirectX File containing a standard mesh to a DirectX File containing a
Progressive Mesh.  Note that due to the amount of analysis that takes
place, this tool can take *a long time* to run. bigship.x takes
approximately 50 minutes to convert to a Progressive Mesh on a P166.


Issues
------

Retained Mode's texture management does not correctly deal with mipmaps
containing palettized textures.  Please use chains with RGB surfaces.
