Microsoft DirectX 8.0 (C++)

Setting Up a View Matrix

The D3DXMatrixLookAtLH and D3DXMatrixLookAtRH helper functions create a view matrix based on the camera location and a look-at point. They use the D3DXVec3Cross, D3DXVec3Dot, D3DXVec3Normalize, and D3DXVec3Subtract helper functions.

The following code example, illustrates the D3DXMatrixLookAtLH function.

D3DXMATRIX* WINAPI D3DXMatrixLookAtLH
    ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
      const D3DXVECTOR3 *pUp )
{
#if DBG
    if(!pOut || !pEye || !pAt || !pUp)
        return NULL;
#endif

    D3DXVECTOR3 XAxis, YAxis, ZAxis;

    // Get the z basis vector, which points straight ahead; the
    // difference from the eye point to the look-at point. This is the 
    // direction of the gaze (+z).
    D3DXVec3Subtract(&ZAxis, pAt, pEye);

    // Normalize the z basis vector.
    D3DXVec3Normalize(&ZAxis, &ZAxis);

    // Compute the orthogonal axes from the cross product of the gaze 
    // and the pUp vector.
    D3DXVec3Cross(&XAxis, pUp, &ZAxis);
    D3DXVec3Normalize(&XAxis, &XAxis);
    D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);

    // Start building the matrix. The first three rows contain the 
    // basis vectors used to rotate the view to point at the look-at 
    // point. The fourth row contains the translation values. 
    // Rotations are still about the eyepoint.
    pOut->_11 = XAxis.x;
    pOut->_21 = XAxis.y;
    pOut->_31 = XAxis.z;
    pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);

    pOut->_12 = YAxis.x;
    pOut->_22 = YAxis.y;
    pOut->_32 = YAxis.z;
    pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);

    pOut->_13 = ZAxis.x;
    pOut->_23 = ZAxis.y;
    pOut->_33 = ZAxis.z;
    pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);

    pOut->_14 = 0.0f;
    pOut->_24 = 0.0f;
    pOut->_34 = 0.0f;
    pOut->_44 = 1.0f;

    return pOut;
}

As with the world transformation, you call the IDirect3DDevice8::SetTransform method to set the view transformation, specifying the D3DTS_VIEW flag in the first parameter. For more information, see Setting Transformations.

Performance Optimization Note  Microsoft® Direct3D® uses the world and view matrices that you set to configure several internal data structures. Each time you set a new world or view matrix, the system recalculates the associated internal structures. Setting these matrices frequently—for example, 20,000 times per frame—is computationally expensive. You can minimize the number of required calculations by concatenating your world and view matrices into a world-view matrix that you set as the world matrix, and then setting the view matrix to the identity. Keep cached copies of individual world and view matrices that you can modify, concatenate, and reset the world matrix as needed. For clarity, Direct3D samples rarely employ this optimization.