3 FlexibleVertexFormat
Chuck Walbourn редактировал(а) эту страницу 2022-04-26 18:29:59 -07:00
Utilities

This contains helper functions for working with Direct3D 9 legacy FVF codes and Direct3D 9 vertex decls. This is useful for tools parsing through older resources, X files, etc.

Header

#include "FlexibleVertexFormat.h"

If the <d3d11.h> header is included before you include FlexibleVertexFormat.h, you get the DirectX 11 input layout function. If the <d3d12.h> header is included before you include FlexibleVertexFormat.h, you get the DirectX 12 version.

This header includes the d3d9.h header, so it only supports the "Win32 desktop" API partition (WINAPI_FAMILY_DESKTOP_APP).

Namespace

The functions in this header are in the FVF C++ namespace.

Functions

  • ComputeVertexSize: This function computes the vertex size from an FVF code or for a specific 'stream slot' of a Direct3D 9 vertex decl. It returns 0 for invalid args or if the decl exceeds MAXD3DDECLLENGTH (64).

There are two overloads for Direct3D 9 vertex decls. The size_t ComputeVertexSize(const D3DVERTEXELEMENT9* pDecl, size_t maxDeclLength, uint32_t stream); version is the more secure function since it's explictily bounded by a parameter.

  • GetDeclLength: This returns the length of a Direct3D 9 vertex decl. This function will return 0 if the walking of the decl exceeds MAXD3DDECLLENGTH (64).

  • CreateDeclFromFVF: This computes a Direct3D 9 vertex decl as a vector based on the input FVF code. It returns false on failure (such as an invalid FVF code).

  • CreateInputLayoutFromFVF: This computes a DirectX11 or DirectX 12 input layout as a vector based on the input FVF code. It returns false on failure (such as an invalid FVF code).

  • ComputeFVF: This function attempts to compute an FVF code given a Direct3D 9 vertex decl. It returns 0 if the decl is not compatible with any FVF code.

There are two overloads for Direct3D 9 vertex decls. The uint32_t ComputeFVF(const D3DVERTEXELEMENT9* pDecl, size_t maxDeclLength); version is the more secure function since it's explictily bounded by a parameter.

Examples

Here is a simple example of creating a DirectX 11 input layout from a FVF code.

#include <d3d11.h>
#include "FlexibleVertexFormat.h"

std::vector<D3D11_INPUT_ELEMENT_DESC> il;
if (!FVF::CreateInputLayoutFromFVF(
          D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1,
          il))
{
    // error  
}

The resulting il vector contains 4 elements:

{ "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL",      0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR",       0, DXGI_FORMAT_B8G8R8A8_UNORM,  0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD",    0, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },

Remarks

The functionality for these functions is similar to the legacy D3DX9 functions for working with FVF codes. These versions perform more bounds-checking and validation. In addition, these functions support the 4-float D3DFVF_XYZW FVF code which was not handled by the D3DX9 functions (it was added for use only for the programmable pipeline, and FVF codes were primarily associated with the fixed-function pipeline).

  • More than 8 texture coordinates are considered invalid FVF codes.

  • Use of 5 betas (D3DFVF_XYZB5) without D3DFVF_LASTBETA_UBYTE4 or D3DFVF_LASTBETA_UBYTE4 is considered an invalid FVF code.

  • If both D3DFVF_LASTBETA_UBYTE4 and D3DFVF_LASTBETA_D3DCOLOR are used at the same time with one of the beta weight positions, then D3DFVF_LASTBETA_UBYTE4 takes precedence.

  • The DirectX 11 / DirectX 12 input layouts are produced using the SV_Position semantic rather than POSITION.