Microsoft DirectX 8.1 (Visual Basic)

Using Higher-Order Primitives

This section shows you how to use higher-order primitives in your application.

Determining Higher-Order Primitive Support

The DevCaps member of D3DCAPS8 contains values from the CONST_D3DDEVCAPSFLAGS enumeration which can be queried to determine the level of support for operations involving higher-order primitives. The following table lists the device capabilities related to higher-order primitives in Microsoft® DirectX® 8.1.

Device capability Description
D3DDEVCAPS_NPATCHES Device supports N-patches.
D3DDEVCAPS_QUINTICRTPATCHES Device supports quintic Bézier curves and B-splines.
D3DDEVCAPS_RTPATCHES Device supports rectangular and triangular (RT) patches.
D3DDEVCAPS_RTPATCHHANDLEZERO RT-patches might be drawn efficiently using handle zero.

Note that D3DDEVCAPS_RTPATCHHANDLEZERO does not mean that a patch with handle zero can be drawn. A handle zero patch can always be drawn, whether this device capability is set or not. When this capability is set, the hardware architecture does not require caching of any information and that uncached patches (handle zero) be drawn as efficiently as cached ones.

Drawing Patches

You can use the following methods to draw patches in Microsoft® Direct3D® for DirectX 8.1.

DrawRectPatch draws a rectangular high-order patch specified by the Surface parameter using the currently set streams. The Handle parameter is used to associate the patch with a handle, so that the next time the patch is drawn, there is no need to respecify Surface. This makes it possible to precompute and cache forward difference coefficients or other information, which in turn enables subsequent calls to DrawRectPatch using the same handle to execute efficiently.

It is intended that for static patches, an application would set the vertex shader and appropriate streams, supply patch information in the Surface parameter, and specify a handle so that Direct3D can capture and cache information. The application can then call DrawRectPatch with Surface set to ByVal 0 to efficiently draw the patch. When drawing a cached patch, the currently set streams are ignored. However, you can override the cached NumSegments by specifying new values for NumSegments. Also, it is required to set the same vertex shader when rendering a cached patch as was set when it was captured.

For dynamic patches, the patch data changes for every rendering of the patch, so it is not efficient to cache information. The application can convey this to Direct3D by setting Handle to 0. In this case, Direct3D draws the patch using the currently set streams and the NumSegments values and does not cache any information. It is not valid to simultaneously set Handle to 0 and Surface to ByVal 0.

By respecifying Surface for the same handle, the application can overwrite the previously cached information.

If NumSegments is set to ByVal 0, then the tessellator uses D3DRS_PATCHSEGMENTS to control the amount of tessellation. In this case, obviously, the same tessellation is used for all sides. There are no special methods for N-patches. Tessellation is simply controlled by D3DRS_PATCHSEGMENTS. It is necessary to supply normals.

DrawTriPatch is similar to DrawRectPatch, except that it draws a triangular high-order patch.

Generating Normals and Texture Coordinates

If you are using a flexible vertex format (FVF) shader, automatic generation of normals and texture coordinates is not possible.

For normals, you can either directly supply them to Direct3D or have Direct3D calculate them for you. To have Direct3D generate normals for you, add D3DVSD_TESSNORMAL and D3DVSD_STREAM_TESS to your vertex declaration. D3DVSD_STREAM_TESS is a delimiter that begins the virtual stream section. One or more tokens (D3DVSD_TESSNORMAL or D3DVSD_TESSUV) can follow this delimiter. The code sample below shows the vertex declaration that you would use to have Direct3D generate normals.

Dim decl(4) As Long

'Vertex data
decl(0) = D3DVSD_STREAM(0)
decl(1) = D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3)

' Data generation section implemented as a virtual stream
decl(2) = D3DVSD_STREAM_TESS()

' Generate normal using the position input and
'   copy it to the normal register (output).
decl(3) = D3DVSD_TESSNORMAL(D3DVSDE_POSITION, D3DVSDE_NORMAL)

decl(4) = D3DVSD_END()

To have texture coordinates automatically generated, add the D3DVSD_TESSUV to your declaration after the D3DVSD_STREAM_TESS delimiter.

Dim decl(4) As Long

'Vertex data
decl(0) = D3DVSD_STREAM(0)
decl(1) = D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3)

' Data generation section implemented as a virtual stream
decl(2) = D3DVSD_STREAM_TESS()

' Generate texture coordinates 
decl(3) = D3DVSD_TESSUV(D3DVSDE_TEXCOORD0)

decl(4) = D3DVSD_END()

The coordinates generated for rectangular patches are spline based coordinates as illustrated by the images below.

Spline based coordinates

The coordinates generated for triangular patches are barycentric spline-based coordinates as illustrated by the images below.

Barycentric spline based coordinates

If an application wants to change the range of the generated texture coordinates, this can be done using texture transforms.