Share via


Introdução (DirectXMath)

A Biblioteca DirectXMath implementa uma interface ideal e portátil para operações de álgebra aritmética e linear em vetores de ponto flutuante de precisão única (2D, 3D e 4D) ou matrizes (3×3 e 4×4). A biblioteca tem algum suporte limitado para operações de vetor inteiro. Essas operações são usadas extensivamente na renderização e animação por programas gráficos. Não há suporte para vetores de precisão dupla (incluindo longs, shorts ou bytes) e apenas operações de vetor inteiro limitadas.

A biblioteca está disponível em várias plataformas do Windows. Como a biblioteca fornece funcionalidades não disponíveis anteriormente, essa versão substitui as seguintes bibliotecas:

  • Biblioteca de Matemática do Xbox fornecida pelo cabeçalho Xboxmath.h
  • Biblioteca D3DX 9 fornecida pelas DLLs D3DX 9
  • Biblioteca matemática D3DX 10 fornecida por meio das DLLs D3DX 10
  • Biblioteca matemática XNA fornecida pelo cabeçalho xnamath.h no SDK do DirectX e no XDK do Xbox 360

Estas seções descrevem os conceitos básicos de introdução.

Baixar

A biblioteca DirectXMath está incluída no SDK do Windows. Como alternativa, você pode baixá-lo no GitHub/Microsoft/DirectXMath. Este site também contém projetos de exemplo relacionados.

Requisitos do sistema Run-Time

A Biblioteca DirectXMath usa instruções de processador especializadas para operações de vetor quando elas estão disponíveis. Para evitar que um programa gere falhas de "exceção de instrução desconhecida", marcar para suporte ao processador chamando XMVerifyCPUSupport antes de usar a Biblioteca DirectXMath.

Estes são os requisitos básicos de suporte em tempo de execução da Biblioteca DirectXMath:

  • A compilação padrão em uma plataforma Windows (x86/x64) requer suporte à instrução SSE/SSE2.
  • A conformidade padrão em uma plataforma Windows RT requer suporte à instrução ARM-NEON.
  • A compilação com _XM_NO_INTRINSICS_ definida requer apenas suporte à operação de ponto flutuante padrão.

Observação

Ao chamar XMVerifyCPUSupport, inclua <windows.h> antes de incluir <DirectXMath.h>. Essa é a única função na biblioteca que requer qualquer conteúdo do <windows.h> para que você não precise incluir <windows.h> em cada módulo que usa <DirectXMath.h>.

 

Visão Geral do design

A Biblioteca DirectXMath dá suporte principalmente à linguagem de programação C++. A biblioteca é implementada usando rotinas embutidas nos arquivos de cabeçalho, DirectXMath*.inl, DirectXPackedVector.inl e DirectXCollision.inl. Essa implementação usa intrínsecos do compilador de alto desempenho.

A Biblioteca DirectXMath fornece:

  • Uma implementação usando intrínsecos SSE/SSE2.
  • Uma implementação sem intrínsecos.
  • Uma implementação usando intrínsecos ARM-NEON.

Como a biblioteca é entregue usando arquivos de cabeçalho, use o código-fonte para personalizar e otimizar para seu próprio aplicativo.

Convenção de matriz

O DirectXMath usa matrizes principais de linha, vetores de linha e pré-multiplicação. A entrega é determinada por qual versão da função é usada (RH vs. LH), caso contrário, a função funciona com coordenadas de exibição à esquerda ou à direita.

Para referência, o Direct3D tem usado historicamente o sistema de coordenadas canhoto, matrizes principais de linha, vetores de linha e pré-multiplicação. O Direct3D moderno não tem um requisito forte para coordenadas esquerda versus direita e, normalmente, sombreadores HLSL são padrão para consumir matrizes principais de coluna. Consulte Ordenação de Matriz HLSL para obter detalhes.

Uso básico

Para usar as funções da Biblioteca DirectXMath, inclua os cabeçalhos DirectXMath.h, DirectXPackedVector.h, DirectXColors.h e/ou DirectXCollision.h. Os cabeçalhos são encontrados no Kit de Desenvolvimento de Software do Windows para aplicativos da Windows Store.

Diretrizes de uso de tipo

Os tipos XMVECTOR e XMMATRIX são os cavalos de trabalho para a Biblioteca DirectXMath. Cada operação consome ou produz dados desses tipos. Trabalhar com eles é fundamental para usar a biblioteca. No entanto, como o DirectXMath usa os conjuntos de instruções SIMD, esses tipos de dados estão sujeitos a uma série de restrições. É fundamental que você entenda essas restrições se quiser fazer um bom uso das funções DirectXMath.

Você deve pensar em XMVECTOR como um proxy para um registro de hardware SIMD e XMMATRIX como um proxy para um agrupamento lógico de quatro registros de hardware SIMD. Esses tipos são anotados para indicar que exigem alinhamento de 16 bytes para funcionar corretamente. O compilador os colocará automaticamente na pilha quando forem usados como uma variável local ou os colocará no segmento de dados quando forem usados como uma variável global. Com convenções adequadas, elas também podem ser passadas com segurança como parâmetros para uma função (consulte Convenções de chamada para obter detalhes).

No entanto, as alocações do heap são mais complicadas. Dessa forma, você precisa ter cuidado sempre que usar XMVECTOR ou XMMATRIX como membro de uma classe ou estrutura a ser alocada do heap. No Windows x64, todas as alocações de heap são alinhadas a 16 bytes, mas para o Windows x86, elas são alinhadas apenas a 8 bytes. Há opções para alocar estruturas do heap com alinhamento de 16 bytes (consulte Alinhar corretamente alocações). Para programas C++, você pode usar as sobrecargas do operador new/delete/new[]/delete[] (globalmente ou específicas da classe) para impor o alinhamento ideal, se desejado.

Observação

Como alternativa para impor o alinhamento em sua classe C++ diretamente sobrecarregando nova/exclusão, você pode usar o idioma pImpl. Se você garantir que sua classe Impl esteja alinhada por meio de _aligned_malloc internamente, poderá usar livremente tipos alinhados na implementação interna. Essa é uma boa opção quando a classe 'public' é uma classe ref Windows Runtime ou destina-se a ser usada com std::shared_ptr<>, o que de outra forma pode interromper o alinhamento cuidadoso.

 

No entanto, muitas vezes é mais fácil e mais compacto evitar o uso de XMVECTOR ou XMMATRIX diretamente em uma classe ou estrutura. Em vez disso, use XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4 e assim por diante, como membros de sua estrutura. Além disso, você pode usar as funções Carregamento de Vetor e Armazenamento de Vetores para mover os dados com eficiência para variáveis locais XMVECTOR ou XMMATRIX , executar cálculos e armazenar os resultados. Também há funções de streaming (XMVector3TransformStream, XMVector4TransformStream e assim por diante) que operam com eficiência diretamente em matrizes desses tipos de dados.

Criando vetores

VETORES CONSTANTES

Muitas operações exigem o uso de constantes em cálculos vetoriais e há várias maneiras de carregar um XMVECTOR com os valores desejados.

  • Se estiver carregando uma constante escalar em todos os elementos de um XMVECTOR, use XMVectorReplicate ou XMVectorReplicateInt.

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • Se estiver usando uma constante de vetor com valores fixos diferentes como um XMVECTOR, use as estruturas XMVECTORF32, XMVECTORU32, XMVECTORI32 ou XMVECTORU8 . Eles podem ser referenciados diretamente em qualquer lugar em que você passe um valor XMVECTOR .

    static const XMVECTORF32 vFactors = { 1.0f, 2.0f, 3.0f, 4.0f };
    

    Observação

    Não use listas de inicializadores diretamente com XMVECTOR (ou seja, XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f }). Esse código é ineficiente e não é portátil em todas as plataformas compatíveis com o DirectXMath.

     

  • O DirectXMath inclui várias constantes globais predefinidas que você pode usar em seu código (g_XMOne, g_XMOne3, g_XMTwo, g_XMOneHalf, g_XMHalfPi, g_XMPi e assim por diante). Pesquise o cabeçalho DirectXMath.h para obter os valores XMGLOBALCONST .

  • Há um conjunto de constantes de vetor para cores RGB comuns (Vermelho, Verde, Azul, Amarelo e assim por diante). Para obter mais informações sobre essas constantes de vetor, consulte DirectXColors.h e o namespace DirectX::Colors.

VETORES DE VARIÁVEIS

VETORES DE VETORES

  • Se criar um vetor de outro vetor com um componente específico definido como uma variável, você poderá considerar o uso do Vector Accessor Functions.

    XMVECTOR v2 = XMVectorSetW( v1, fw );
    
  • Se estiver criando um vetor de outro vetor com um único componente replicado, use XMVectorSplatX, XMVectorSplatY, XMVectorSplatZ e XMVectorSplatW.

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • Se estiver criando um vetor de outro vetor ou par de vetores com componentes reordenados, consulte XMVectorSwizzle e XMVectorPermute.

    XMVECTOR v2 = XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_W, XM_SWIZZLE_X>( v1 );
    
    XMVECTOR v3 = XMVectorPermute<XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_0X, XM_PERMUTE_1Z>( v1, v2 );
    

VETORES DA MEMÓRIA

Extraindo componentes de vetores

O processamento simd é mais eficiente quando os dados são carregados nos registros SIMD e totalmente processados antes de extrair os resultados. A conversão entre formulários escalares e vetoriais é ineficiente, portanto, recomendamos que você faça isso somente quando necessário. Por esse motivo, as funções na biblioteca DirectXMath que produzem um valor escalar são retornadas em uma forma de vetor em que o resultado escalar é replicado no vetor resultante (ou seja, XMVector2Dot, XMVector3Length e assim por diante). No entanto, quando você precisa de valores escalares, aqui estão algumas opções sobre como fazer isso:

  • Se uma única resposta escalar for computada, o uso das funções de acessador de vetor será apropriado:

    float f = XMVectorGetX( v );
    
  • Se vários componentes do vetor precisarem ser extraídos, considere armazenar o vetor em uma estrutura de memória e lê-lo novamente. Por exemplo:

    XMFLOAT4A t;
    XMStoreFloat4A( &t, v );
    // t.x, t.y, t.z, and t.w can be individually accessed now
    
  • A forma mais eficiente de processamento de vetor é usar o streaming de memória para memória em que os dados de entrada são carregados da memória (usando funções de carregamento de vetor), processados totalmente no formato SIMD e gravados na memória (usando funções de repositório de vetores).

Guia de programação do DirectXMath