87 DirectXMesh
Chuck Walbourn редактировал(а) эту страницу 2024-05-14 15:21:24 -07:00

The DirectXMesh library includes various geometry processing functions. This is intended primarily for tool usage.

Headers

The majority of the header files here are intended for internal implementation of the library only (DirectXMeshP.h and scoped.h). Only DirectXMesh.h (and DirectXMesh.inl) is meant as a 'public' header for the library.

#include "DirectXMesh.h"

By default, the library supports Direct3D 11. If you want to support Direct3D 12, then you need to #include <d3d12.h> before you do #include "DirectXMesh.h".

Namespace

All the functions in the library are in the DirectX C++ namespace.

Classes

  • VBReader - Vertex buffer reader class for extracting elements from a VB
  • VBWriter - Vertex buffer writer class for inserting elements into a VB

Functions

Normals, tangents, and bi-tangents

Geometric meshes often must include surface information for lighting computations.

A normal is defined as surface normal perpendicular to the mesh. Triangular meshes imply a face normal defined by the winding order of the vertices of the triangles (typically counter-clockwise, although clock-wise winding can also be used). For efficient rendering, vertex normals are used for rendering rather than face normals.

A tangent and a bi-tangent are gradient direction vectors along the surface of a mesh. Together with the normal they describe a full 3-axis coordinate system useful for many advanced lighting techniques.

Adjacency computation

A useful property of geometric meshes is the adjacency relationship between faces of the mesh as defined by sharing triangle edges.

The adjacency is represented as an array of uint32_t index values with 3 entries for each triangular face in the mesh. Each entry is the face index of the triangular face that is adjacent to one edge of the triangular face (hence as there are three edges, there can be up to 3 triangular faces that share an edge). If there is no adjacent face, the index is set to -1u ( a.k.a. static_cast<uint32_t>(-1)).

The point representative (aka point rep) is an array of uint32_t index values with one entry for each vertex in the mesh. Each entry is the vertex index of a vertex with a unique position. If there are no vertices that share the same location, each entry of the pointrep array is the identity (i.e. pointrep[ i ] is i). If there are duplicated vertex positions in the mesh, then some entry will point to another 'representative' vertex index.

Mesh cleanup and validation

Triangular mesh descriptions can contain a number of errors which result in invalid or failed geometric operations. There are also a number of cases where a triangular mesh description can cause mesh algorithms to fail. These functions can detect and resolve such issues.

  • Validate - Checks if the mesh description is invalid, and optionally includes diagnostic messages describing the problem(s) encountered
  • Clean - These functions "clean" a mesh by eliminating common problems by modifying indices, adjacency, and/or duplicating vertices.

Mesh utilities

  • ConcatenateMesh - Merges two or more meshes through simple concatenation.
  • WeldVertices - Welds together replicated vertices that have equal attributes using a supplied test function.

Mesh optimization

Direct3D can render valid meshes with the same visual results no matter how the data is ordered, but the efficiency of the rendering performance can be impacted by ordering that is well-matched to modern GPUs. Mesh optimization is a process for reordering faces and vertices to provide the same visual result, with improved utilization of hardware resources.

  • AttributeSort - Reorders the faces grouping together all those that use the same attribute id
  • OptimizeFaces - Reorders faces to improve post-transform vertex cache reuse using the Hoppe algorithm
  • OptimizeFacesLRU - Reorders faces to improve post-transform vertex cache reuse using the Forsyth algorithm
  • OptimizeVertices - Reorders vertices in order of use by the index buffer which optimizes for the vertex shader pre-transform cache

Performing a mesh optimization

A complete mesh optimization includes the following steps:

HoppeForsyth
GenerateAdjacencyAndPointReps
Clean Clean
AttributeSort AttributeSort
ReorderIBAndAdjacencyReorderIB
OptimizeFacesOptimizeFacesLRU
ReorderIBReorderIB
OptimizeVerticesOptimizeVertices
FinalizeIBFinalizeIB
FinalizeVBFinalizeVB

Remap functions

These utility functions apply the reordering maps generated by Mesh optimization.

Face remap array

  • ReorderIB - Reorders a 16-bit or 32-bit index buffer based on a face remap array
  • ReorderIBAndAdjacency - Reorders a 16-bit or 32-bit index buffer and adjacency based on a face remap array

Vertex remap array

  • FinalizeIB - Finishes mesh optimization by updating an index buffer based on a vertex remap
  • FinalizeVB - Finishes mesh optimization by reordering vertices and/or adding duplicated vertices for the vertex buffer
  • FinalizeVBAndPointReps - Finishes mesh optimization by reordering vertices and/or adding duplicated vertices for the vertex buffer, and the point representatives
  • CompactVB - Finishes mesh optimization by reordering vertices and trimming any trailing unused vertices.

Meshlet generation

Utility functions

DXGI Format Utilities

  • IsValidVB - Returns false if the DXGI format is not valid for use in a Vertex Buffer (VB) input layout

  • IsValidIB - Returns false if the DXGI format is not valid for use as an Index Buffer (IB) format

  • BytesPerElement - Returns the number of bytes per element for a given DXGI format. This function returns 0 for a format that is not valid for use as a VB input layout or an IB. For example, DXGI_FORMAT_R32G32B32_FLOAT returns 12 bytes.

Input Layout Descriptor Utilities

  • IsValid - Returns false if the given Direct3D input layout description is invalid.

  • ComputeInputLayout - Returns the byte offsets for each element of an input layout and the implied vertex stride from a given Direct3D input layout description.

Attribute Utilities

  • ComputeSubsets - Returns a list of face offsets and counts based on the input attributes id array.

Mesh Optimization Utilities

  • ComputeVertexCacheMissRate - Returns the average cache miss ratio (ACMR) and average triangle vertex re-use (ATVR) for the post-transform vertex cache.

Parameters

Parameters The following standard parameters are used throughout the library:

  • indices: A 16-bit or 32-bit indexed description of the triangles in a mesh. This must have 3 * nFaces entries, and every group of 3 describes the vertices for a triangle face.

    • This is the index buffer data suited for use with D3D1x_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
    • An entry of -1u is reserved as 'unused' (Direct3D interprets this special value as a strip restart). Any face containing one or more -1u entries is considered an 'unused' face.
  • nFaces: Number of triangular faces in the mesh.

  • positions: The vertex positions of the mesh as indexed by entries in indices. This must have nVerts entries.

  • texcoords: The UV texture coordinates of the mesh as indexed by entries in indices. This must have nVerts entries.

  • nVerts: Number of vertices in the mesh.

  • pointRep: A 32-bit index array with nVerts entries containing the point representatives for each vertex in a mesh.

    • Should be set to -1u to indicate an unused entry.
    • These are in the same vertex order as the positions array.
  • adjacency: A 32-bit index array with nFaces * 3 entries containing the edge adjacencies for each face in a mesh.

    • Each triple describes the adjacent face triangles for a given face in the following edge order: (v1v2 / v2v3 / v3v1).
    • Should be set to -1u to indicate an unused entry (i.e. there is no adjacent triangle on that edge).
    • These are in the same face order as the indices array.
  • attributes: A 32-bit index array with nFaces entries which contains the attribute id for each face in the mesh. Typically this is a 'material ID' or some other grouping that indicates sections of the mesh that can be submitted for drawing as a unit.

    • These are in the same face order as the indices array.

Adding to a VS solution

Using project-to-project references

In your application's solution, right-click on the Solution and use Add \ Existing Project... to add the appropriate .vcxproj file to your solution.

DirectXMesh_Desktop_2022 Windows desktop applications for Windows 7 Service Pack 1 or later building with VS 2022 Community, Professional or higher with latest installed Windows 10 SDK.
DirectXMesh_Desktop_2022_Win10 Windows desktop applications for Windows 10 building with VS 2022 Community, Professional or higher with the latest installed Windows 10 SDK. This includes DirectX 12 support.
DirectXMesh_Windows10_2022 Universal Windows Platform (UWP) apps building with VS 2022 with the latest installed Windows 10 SDK. This includes DirectX 12 support.
DirectXMesh_Desktop_2019 Windows desktop applications for Windows 7 Service Pack 1 or later building with VS 2019 Community, Professional or higher with latest installed Windows 10 SDK.
DirectXMesh_Desktop_2019_Win10 Windows desktop applications for Windows 10 building with VS 2019 Community, Professional or higher with the latest installed Windows 10 SDK. This includes DirectX 12 support.
DirectXMesh_GDK_2019 Windows 10 and Xbox games building with VS 2019 using the Microsoft GDK.

For VS 2019, use of the 16.11 is required as all previous versions are no longer supported.

In your application's project, right-click on the Project and use "References...", then "Add New Reference...", and then check the DirectXMesh project name and click OK. For a Universal Windows Platform (UWP) app or Xbox One solution, you need to set Reference Assembly Output to false since DirectXMesh is a static C++ library and not a WinRT component.

In your application's project settings, on the "C++ / General" page set Configuration to "All Configurations", set Platform to "All Platforms", and then add the relative path to DirectXMesh;--assuming you have the DirectXMesh folder in the same directory as your sln file, it should be $(SolutionDir$)\DirectXMesh;--to the Additional Include Directories properties. Click Apply.

See the Visual C++ Team Blog

Using NuGet package manager

Alternatively you can use NuGet to install one of the DirectXMesh packages. Use Project / Manage NuGet Packages... then select "Online" and search for "DirectXMesh".

directxmesh_desktop_2019 This NuGet package is configured for Windows desktop C++ applications building with VS 2019 or VS 2022 Community/Professional or higher for Windows 7 Service Pack 1 or later.
directxmesh_desktop_win10 This NuGet package is configured for Windows desktop C++ applications building with VS 2019 or VS 2022 Community/Professional or higher for Windows 10. This includes DirectX 12 support.
directxmesh_uwp This NuGet package is configured for Universal Windows Platform apps for Windows 10 building with VS 2019 or VS 2022 Community/Professional or higher. This includes DirectX 12 support.

You should use the NuGet interface to check for updates if you have an older version installed.

Archived

These packages are no longer supported:

Using the vcpkg C++ library manager

DirectXMesh is also available through the vcpkg C++ Library Manager.

vcpkg install directxmesh

For the 64-bit version of the library, use:

vcpkg install directxmesh:x64-windows

For the Universal Windows Platform (UWP) versions, use:

vcpkg install directxmesh:x64-uwp

arm, arm64, x86, x64, windows, windows-static, windows-static-md, and uwp triplets are supported.

The vcpkg port supports three optional features. The default is to build without DirectX 12 support except for UWP which always includes it.

  • tools: Installs meshconvert.exe command-line tool
  • spectre: Builds the library with Spectre-mitigation enabled
  • dx12: Adds DirectX 12 API support functions for Windows 10/Windows 11.

For Windows Subsystem for Linux, use:

./vcpkg install directxmesh:x64-linux
./vcpkg install directxmesh:arm64-linux

Non-Win32 support requires a C++17 conformant compiler & library. GNUC 9 will work; GNUC 11.3 or later is recommended.

For Xbox Series X|S with the Microsoft GDK with Xbox Extensions installed:

./vcpkg install directxmesh:x64-xbox-scarlett

For Xbox One with the Microsoft GDK with Xbox Extensions installed:

./vcpkg install directxmesh:x64-xbox-xboxone

CMake

You can reference the DirectXMesh CMake package using:

find_package(directxmesh CONFIG REQUIRED)

target_link_libraries(foo Microsoft::DirectXMesh)

The Utilities folder with WaveFrontReader.h et al is also available in the CMake package as an opt-in component:

find_package(directxmesh CONFIG REQUIRED COMPONENTS library utils)

target_link_libraries(foo Microsoft::DirectXMesh Microsoft::DirectXMesh::Utilities)

If using CMakePresets.json set the environment variable VCPKG_ROOT and add:

"cacheVariables": {
  CMAKE_TOOLCHAIN_FILE": {
    value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
    "type": "FILEPATH"
  }
},

If not using vcpkg, you have to provide a per-configuration path to the individual installed package in the directxmesh_DIR variable. Otherwise the find_package will fail.

Additional Information

Implementation