Этот файл содержит невидимые символы Юникода, которые могут быть отображены не так, как показано ниже. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы показать скрытые символы.
DIRECTX MESH LIBRARY (DirectXMesh)
------------------------------------
Copyright (c) Microsoft Corporation. All rights reserved.
November 14, 2014
This package contains DirectXMesh, a shared source library for performing various geometry
content processing operations including generating normals and tangent frames, triangle
adjacency computations, and vertex cache optimization.
The source is written for Visual Studio 2010, 2012, or 2013. It is recommended that you
make use of the Windows 8.1 SDK and Windows 7 Service Pack 1 or later.
Details on using the Windows 8.1 SDK with VS 2010 are described on the Visual C++ Team Blog:
<http://blogs.msdn.com/b/vcblog/archive/2012/11/23/using-the-windows-8-sdk-with-visual-studio-2010-configuring-multiple-projects.aspx>
These components are designed to work without requiring any content from the DirectX SDK. For details,
see "Where is the DirectX SDK?" <http://msdn.microsoft.com/en-us/library/ee663275.aspx>.
DirectXMesh\
This contains the DirectXMesh library.
Note that the majority of the header files here are intended for internal implementation
of the library only (DirectXMeshP.h and scoped.h). Only DirectXMesh.h is meant as a
'public' header for the library.
Utilities\
This contains helper code related to mesh processing that is not general enough to be
part of the DirectXMesh library.
WaveFrontReader.h - Contains a simple C++ class for reading mesh data from a WaveFront OBJ file.
Meshconvert\
This DirectXMesh sample is an implementation of the "meshconvert" command-line texture utility
from the DirectX SDK utilizing DirectXMesh rather than D3DX.
Note this tool does not support legacy .X files, but can export CMO, SDKMESH, and VBO files.
All content and source code for this package are bound to the Microsoft Public License (Ms-PL)
<http://www.microsoft.com/en-us/openness/licenses.aspx#MPL>.
For the latest version of DirectXMesh, more detailed documentation, discussion forums, bug
reports and feature requests, please visit the Codeplex site.
http://go.microsoft.com/fwlink/?LinkID=324981
----------------------------------
Normals, tangents, and bi-tangents
----------------------------------
Geometric meshes often must include surface information for lighting computations. DirectXMesh implements
functions for computing this from mesh triangles.
std::unique_ptr<WaveFrontReader<uint16_t>> mesh( new WaveFrontReader<uint16_t>() );
if ( FAILED( mesh->Load( L"test.obj" ) ) )
// Error
if ( mesh->hasNormals )
// Skip next computation
size_t nFaces = mesh->indices.size() / 3;
size_t nVerts = mesh->vertices.size();
std::unique_ptr<XMFLOAT3[]> pos( new XMFLOAT3[ nVerts ] );
for( size_t j = 0; j < nVerts; ++j )
pos.get()[ j ] = mesh->vertices[ j ].position;
std::unique_ptr<XMFLOAT3[]> normals( new XMFLOAT3[ nVerts ] );
if ( FAILED( ComputeNormals( &mesh->indices.front(), nFaces, pos.get(), nVerts, CNORM_DEFAULT, normals.get() ) ) )
// Error
if ( !mesh->hasTexcoords )
// Skip next computation
std::unique_ptr<XMFLOAT2[]> texcoords( new XMFLOAT2[ nVerts ] );
for( size_t j = 0; j < nVerts; ++j )
texcoords.get()[ j ] = mesh->vertices[ j ].textureCoordinate;
std::unique_ptr<XMFLOAT3[]> tangents( new XMFLOAT3[ nVerts ] );
std::unique_ptr<XMFLOAT3[]> bitangents( new XMFLOAT3[ nVerts ] );
if ( FAILED( ComputeTangentFrame( &mesh->indices.front(), nFaces,
pos.get(), normals.get(), texcoords.get(), nVerts,
tangents.get(), bitangents.get() ) ) )
// Error
--------------
Mesh adjacency
--------------
A useful property of geometric meshes is the adjacency relationship between faces of the mesh as
defined by sharing triangle edges. DirectXMesh implements a number of functions that require
adjacency information to function.
std::unique_ptr<WaveFrontReader<uint16_t>> mesh( new WaveFrontReader<uint16_t>() );
if ( FAILED( mesh->Load( L"test.obj" ) ) )
// Error
size_t nFaces = mesh->indices.size() / 3;
size_t nVerts = mesh->vertices.size();
std::unique_ptr<XMFLOAT3[]> pos( new XMFLOAT3[ nVerts ] );
for( size_t j = 0; j < nVerts; ++j )
pos.get()[ j ] = mesh->vertices[ j ].position;
std::unique_ptr<uint32_t[]> adj( new uint32_t[ mesh->indices.size() ] );
if ( FAILED( GenerateAdjacencyAndPointReps( &mesh->indices.front(), nFaces, pos.get(), nVerts,
0.f, nullptr, adj.get() ) ) )
// Error
---------------------------
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. DirectXMesh implements a number of functions to detect and
resolve such issues.
std::unique_ptr<WaveFrontReader<uint16_t>> mesh( new WaveFrontReader<uint16_t>() );
if ( FAILED( mesh->Load( L"test.obj" ) ) )
// Error
size_t nFaces = mesh->indices.size() / 3;
size_t nVerts = mesh->vertices.size();
hr = Validate( &mesh->indices.front(), nFaces, nVerts, nullptr, VALIDATE_DEFAULT );
if ( FAILED(hr) )
// E_FAIL indicates that mesh failed validation
std::unique_ptr<XMFLOAT3[]> pos( new XMFLOAT3[ nVerts ] );
for( size_t j = 0; j < nVerts; ++j )
pos.get()[ j ] = mesh->vertices[ j ].position;
std::unique_ptr<uint32_t[]> adj( new uint32_t[ mesh->indices.size() ] );
if ( FAILED( GenerateAdjacencyAndPointReps( &mesh->indices.front(), nFaces, pos.get(), nVerts,
0.f, nullptr, adj.get() ) ) )
// Error
std::unique_ptr<uint16_t[]> indices( new uint16_t[ nFaces * 3 ] );
memcpy( indices.get(), &mesh->indices.front(), sizeof(uint16_t) * nFaces * 3 ) );
std::vector<uint32_t> dupVerts;
hr = Clean( indices.get(), nFaces, nVerts, adj.get(), nullptr, dupVerts, true );
if ( FAILED(hr) )
// Error
-----------------
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.
std::unique_ptr<WaveFrontReader<uint16_t>> mesh( new WaveFrontReader<uint16_t>() );
if ( FAILED( mesh->Load( L"test.obj" ) ) )
// Error
size_t nFaces = mesh->indices.size() / 3;
size_t nVerts = mesh->vertices.size();
std::unique_ptr<XMFLOAT3[]> pos( new XMFLOAT3[ nVerts ] );
for( size_t j = 0; j < nVerts; ++j )
pos.get()[ j ] = mesh->vertices[ j ].position;
std::unique_ptr<uint32_t[]> adj( new uint32_t[ mesh->indices.size() ] );
if ( FAILED( GenerateAdjacencyAndPointReps( &mesh->indices.front(), nFaces, pos.get(), nVerts,
0.f, nullptr, adj.get() ) ) )
// Error
std::unique_ptr<uint32_t[]> faceRemap( new uint32_t[ nFaces ] );
if ( FAILED( OptimizeFaces( &mesh->indices.front(), nFaces, adj.get(), faceRemap.get() ) ) )
// Error
std::unique_ptr<uint16_t[]> newIndices( new uint16_t[ nFaces * 3 ] );
if ( FAILED( ReorderIB( &mesh->indices.front(), nFaces, faceRemap.get(), newIndices.get() ) ) )
// Error
std::unique_ptr<uint32_t[]> vertRemap( new uint32_t[ nVerts ] );
if ( FAILED( OptimizeVertices( newIndices.get(), nFaces, nVerts, vertRemap.get() ) ) )
// Error
if ( FAILED( FinalizeIB( newIndices.get(), nFaces, vertRemap.get(), nVerts ) ) )
// Error
std::unique_ptr<WaveFrontReader<uint16_t>::Vertex> vb( new WaveFrontReader<uint16_t>::Vertex[ nVerts ] );
if ( FAILED( FinalizeVB( &mesh->vertices.front(), sizeof(WaveFrontReader<uint16_t>::Vertex),
nVerts, nullptr, 0, vertRemap.get(), vb.get() ) ) )
// Error
Further reading:
Hoppe, H.; "Optimization of mesh locality for transparent vertex caching", ACM SIGGRAPH 1999 Proceedings
http://research.microsoft.com/en-us/um/people/hoppe/proj/tvc/
---------------------------
Vertex buffer reader/writer
---------------------------
Mesh processing can require inserting or extracting data from a vertex buffer. The VBReader and VBWriter
classes provide a solution for this based on Direct3D 11 input layouts.
During initialization:
std::unique_ptr<VBReader> reader( new VBReader() );
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT2 Tex;
};
HRESULT hr = reader->Initialize( layout, 2 );
if ( FAILED(hr) )
// Error
hr = reader->AddStream( vbdata, nVerts, 0, sizeof(Vertex) );
if ( FAILED(hr) )
// Error
Note: The VBWriter is set up the same way.
Extracting vertex data:
struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } };
std::unique_ptr<XMVECTOR, aligned_deleter> buff(
reinterpret_cast<XMVECTOR*>( _aligned_malloc( sizeof(XMVECTOR) * nVerts, 16 ) ) );
if ( FAILED( reader->Read( buff.get(), "POSITION", 0, nVerts ) ) )
// Error
Inserting vertex data:
struct aligned_deleter { void operator()(void* p) { _aligned_free(p); } };
std::unique_ptr<XMVECTOR, aligned_deleter> buff(
reinterpret_cast<XMVECTOR*>( _aligned_malloc( sizeof(XMVECTOR) * nVerts, 16 ) ) );
// Store position data into XMVECTOR buff array
if ( FAILED( writer->Write( buff.get(), "POSITION", 0, nVerts ) ) )
// Error
---------------
RELEASE HISTORY
---------------
November 14, 2014
meshconvert: sample improvements and fixes
Added workarounds for potential compiler bug when using VB reader/writer
October 28, 2014
meshconvert command-line sample
Added VBReader/VBWriter::GetElement method
Added more ComputeTangentFrame overloads
Explicit calling-convention annotation for public headers
Windows phone 8.1 platform support
Minor code and project cleanup
June 27, 2014
Original release