Direct3DRMViewport and Direct3DRMViewportArray
The viewport defines how the 3D scene is rendered into a 2D window. The viewport defines a rectangular area on a device that objects will be rendered into.
The viewport uses a Direct3DRMFrame object as a camera. The camera frame defines which scene is rendered and the viewing position and direction. The viewport renders only what is visible along the positive z-axis of the camera frame, with the up direction being in the direction of the positive y-axis.
An application can call the IDirect3DRMViewport::SetCamera method to set a camera for a given viewport. This method sets a viewport's position, direction, and orientation to that of the given camera frame. To retrieve the current camera settings, call the IDirect3DRMViewport::GetCamera method.
The viewing frustum is a 3D volume in a scene positioned relative to the viewport's camera. Objects within the viewing frustum are visible. For perspective viewing, the viewing frustum is the volume of an imaginary pyramid that is between the front clipping plane and the back clipping plane.
The camera is at the tip of the pyramid, and its z-axis runs from the tip of the pyramid to the center of the pyramid's base. The front clipping plane is a distance D from the camera, and the back clipping plane is a distance F from the front clipping plane. An application can set and retrieve these values by using the IDirect3DRMViewport::SetFront, IDirect3DRMViewport::SetBack, IDirect3DRMViewport::GetFront, and IDirect3DRMViewport::GetBack methods. The height of the front clipping plane is 2h and defines the field of view. An application can set and retrieve the value of h by using the IDirect3DRMViewport::SetField and IDirect3DRMViewport::GetField methods.
The angle of view, A, is defined by the following equation, which can be used to calculate a value for h when a particular camera angle is desired:
The viewing frustum is a pyramid only for perspective viewing. For orthographic viewing, the viewing frustum is cuboid. These viewing types (or projection types) are defined by the D3DRMPROJECTIONTYPE enumerated type and used by the IDirect3DRMViewport::GetProjection and IDirect3DRMViewport::SetProjection methods.
Transformations
To render objects with 3D coordinates in a 2D window, the object must be transformed into the camera's frame. A projection matrix is then used to give a four-element homogeneous coordinate [x y z w], which is used to derive a three-element coordinate [x/w y/w z/w], where [x/w y/w] is the coordinate to be used in the window and z/w is the depth, ranging from 0 at the front clipping plane to 1 at the back clipping plane. The projection matrix is a combination of a perspective transformation followed by a scaling and translation to scale the objects into the window.
The following matrix is the projection matrix. In these formulas, h is the half-height of the viewing frustum, F is the position in z-coordinates of the back clipping plane, and D is the position in z-coordinates of the front clipping plane:
The following matrix is the window-scaling matrix. (The scales are dependent on the size and position of the window.) In these formulas, s is the window-scaling factor and o is the window origin:
The following matrix is the viewing matrix. This is a combination of the projection matrix and window matrix, or the dot product of P and W:
The scaling factors and origin sx, sy, ox, and oy are chosen so that the region [-h -h D] to [h h D] fits exactly into either the window's height or the window's width, whichever is larger.
The application can use the IDirect3DRMViewport::Transform and IDirect3DRMViewport::InverseTransform methods to transform vectors to screen coordinates from world coordinates and vice versa. An application can use these methods to support dragging, as shown in the following example:
/*
* Drag a frame by [delta_x delta_y] pixels in the view.
*/
void DragFrame(LPDIRECT3DRMVIEWPORT view,
LPDIRECT3DRMFRAME frame,
LPDIRECT3DRMFRAME scene,
int delta_x, int delta_y)
{
D3DVECTOR p1;
D3DRMVECTOR4D p2;
frame->GetPosition(scene, &p1);
view->Transform(&p2, &p1);
p2.x += delta_x * p2.w;
p2.y += delta_y * p2.w;
view->InverseTransform(&p1, &p2);
frame->SetPosition(scene, p1.x, p1.y, p1.z);
}
An application uses the viewport transformation to ensure that the distance by which the object is moved in world coordinates is scaled by the object's distance from the camera to account for perspective. Note that the result from IDirect3DRMViewport::Transform is a four-element homogeneous vector. This avoids the problems associated with coordinates being scaled by an infinite amount near the camera's position.
The viewport projection matrix produces a well-defined 3D coordinate only for points inside the viewing frustum. For a homogeneous point [x y z w] after projection, this is true if the following equations hold:
Picking
Picking is the process of searching for visuals in the scene given a 2D coordinate in the viewport's window. An application can use the IDirect3DRMViewport::Pick method to retrieve either the closest object in the scene or a depth-sorted list of objects.