Microsoft DirectX 8.1 (Visual Basic)

Using Indexed Vertex Blending

Transform and Render States

Transform states 256-511 are reserved to store up to 256 matrices that can be indexed using 8-bit indices. Use the function below to map indices 0-255 to the corresponding transform states.

Function D3DTS_WORLDMATRIX(index as Long) As Long
    D3DTS_WORLDMATRIX=(index + 256)
End Function

The following code example shows how to use the Direct3DDevice8.SetTransform method to set the matrix at transform state number 256 to an identity matrix.

Dim matBlend1 As D3DMATRIX

Call D3DXMatrixIdentity(matBlend1)
Call m_D3DDevice.SetTransform(D3DTS_WORLDMATRIX(0), matBlend)

To enable or disable indexed vertex blending, set the D3DRS_INDEXVERTEXBLENDENABLE render state to 1. When the render state is enabled, you must pass matrix indices as packed Longs with every vertex. When this render state is disabled and vertex blending is enabled, it is equivalent to having the matrix indices 0, 1, 2, and 3 in every vertex. The code example below uses the Direct3DDevice8.SetRenderState method to enable indexed vertex blending.

Call m_D3DDevice.SetRenderState(D3DRS_INDEXVERTEXBLENDENABLE, 1)

To enable or disable vertex blending, set the D3DRS_VERTEXBLEND render state to a value other than D3DRS_DISABLE from the D3DVERTEXBLENDFLAGS enumerated type. If this render state is not set to D3DRS_DISABLE, then you must pass the required number of weights for each vertex. The following code example uses SetRenderState to enable vertex blending with three weights for each vertex.

Call m_D3DDevice.SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS)

Determining Indexed Vertex Blending Support

Dim d3dCaps As D3DCAPS8

Call D3DDevice.GetDeviceCaps(d3dCaps)
IndexedMatrixMaxSize = d3dCaps.MaxVertexBlendMatrixIndex

If the value set in MaxVertexBlendMatrix is 0, then the device does not support indexed matrices.

Note  When software vertex processing is used, 256 matrices can be used for indexed vertex blending, with or without normal blending.

Passing Matrix Indices to Direct3D

World matrix indices can be passed to Microsoft® Direct3D® by using legacy vertex shaders (FVF) or declarations.

The code example below shows how to use legacy vertex shaders.

Private Type VERTEX
    x As Single
    y As Single
    z As Single
    weight As Single
    matrixIndices As Long
    normal(2) As Single
End Type

Const D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZB2 Or D3DFVF_NORMAL Or _
                             D3DFVF_LASTBETA_UBYTE4)

When a legacy vertex shader is used, matrix indices are passed together with vertex positions using D3DFVF_XYZBn flags. Matrix indices are passed as a packed byte and must be present immediately after the last vertex weight. Vertex weights are also passed using D3DFVF_XYZBn. A packed byte contains index3, index2, index1, and index0, where index0 is located in the lowest byte of the byte. The number of used world-matrix indices is equal to the number passed to the number of matrices used for blending as defined by D3DRS_VERTEXBLEND.

When a declaration is used, D3DVSDE_BLENDINDICES defines the input vertex register to get matrix indices from. Matrix indices must be passed as D3DVSDT_UBYTE4.

The code example below shows how to use declarations. Note that the order of the components is no longer important.

Private Type VERTEX
    x As Single
    y As Single
    z As Single
    matrixIndices As Long
    weight As Single
    normal(2) As Single
End Type

Dim decl(5) As Long

decl(0) = D3DVSD_STREAM(0)
decl(1) = D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3)
decl(2) = D3DVSD_REG(D3DVSDE_BLENDINDICES, D3DVSDT_PACKEDBYTE)
decl(3) = D3DVSD_REG(D3DVSDE_BLENDWEIGHT, D3DVSDT_FLOAT1)
decl(4) = D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3)
decl(5) = D3DVSD_END()