Platform SDK: DirectX

Step 2.2: Perform the 3-D Transformation

[C++]

This section pertains only to application development in Visual Basic. See Direct3D Immediate Mode C/C++ Tutorials.

[Visual Basic]

The Using Alternate Primitive Styles tutorial uses geometric transformation to define the location of the cube relative to the other objects in the scene, to rotate the cube, and to scale the cube in the scene.

Before implementing your 3-D transformation, you will need to retrieve the height and width of the viewport. This information is used to scale the transformed vertices to fit the render window:

Private Sub TransformVertices(d3dDevice As Direct3DDevice7, vVertices() As D3DTLVERTEX, nNumVertices As Integer)
    
    Dim vp As D3DVIEWPORT7
    Dim nClipWidth As Integer
    Dim nClipHeight As Integer
        
    ' Get the height and width of the viewport. This is needed to scale the transformed vertices
    ' to fit the render window.
    d3dDevice.GetViewport vp
    nClipWidth = vp.lWidth / 2
    nClipHeight = vp.lHeight / 2

Direct3D uses matrices to perform transformations. In order to execute a 3-D transformation, you need to retrieve the values of the current matrix set. You do this by calling Direct3DDevice7.GetTransform on the rendering device:

    d3dDevice.GetTransform D3DTRANSFORMSTATE_WORLD, matWorld
    d3dDevice.GetTransform D3DTRANSFORMSTATE_VIEW, matView
    d3dDevice.GetTransform D3DTRANSFORMSTATE_PROJECTION, matProj

You use matrix multiplication to concatenate the matrices:

    Dim matSet As D3DMATRIX
    
    g_dx.IdentityMatrix matSet
     
    ' Concatenate the matrices.
    g_dx.MatrixMultiply matSet, matWorld, matView
    g_dx.MatrixMultiply matSet, matSet, matProj

In the preceding code, a composite matrix, matSet, is calculated to representing the product of the desired transformations. During concatenation, ensure that the matrices are multiplied in the order in which you want them to operate.

For more information on matrix concatenation, see Matrix Concatenation.

Now, you transform each vertex through the current matrix set:

    For i = 0 To nNumVertices - 1
        ' Get the untransformed vertex position.
        x = vVertices(i).sx
        y = vVertices(i).sy
        z = vVertices(i).sz
        
        xp = matSet.rc11 * x + matSet.rc21 * y + matSet.rc31 * z + matSet.rc41
        yp = matSet.rc12 * x + matSet.rc22 * y + matSet.rc32 * z + matSet.rc42
        zp = matSet.rc13 * x + matSet.rc23 * y + matSet.rc33 * z + matSet.rc43
        wp = matSet.rc14 * x + matSet.rc24 * y + matSet.rc34 * z + matSet.rc44

Finally, scale the vertices to screen coordinates. In the following code, the first step flattens the coordinates from 3-D space to 2-D device coordinates by dividing each coordinate by the wp value. Then, the x- and y-components are transformed from device coordinates to screen coordinates.

        vVertices(i).sx = (1# + (xp / wp)) * nClipWidth
        vVertices(i).sy = (1# - (yp / wp)) * nClipHeight
        vVertices(i).sz = zp / wp
        vVertices(i).rhw = wp
   Next i

For more information on 3-D transformations, see 3-D Transformations.

Note  Device coordinates range from -1 to +1 in the viewport. Also, the sz-coordinate will be used in the z-buffer.

Now that you have transformed the cube's eight vertices, you can render a frame of the completed the scene. This is shown in Step 2.3: Render the Scene.