Share via


Introducción (DirectXMath)

La biblioteca DirectXMath implementa una interfaz óptima y portátil para operaciones de álgebra aritmética y lineal en vectores de punto flotante de precisión sencilla (2D, 3D y 4D) o matrices (3×3 y 4×4). La biblioteca tiene cierta compatibilidad limitada con las operaciones de vectores enteros. Estas operaciones se usan ampliamente en la representación y animación por parte de programas gráficos. No hay compatibilidad con vectores de precisión doble (incluidos longs, shorts o bytes) y solo operaciones de vector entero limitadas.

La biblioteca está disponible en una variedad de plataformas Windows. Dado que la biblioteca proporciona funcionalidad no disponible anteriormente, esta versión sustituye a las siguientes bibliotecas:

  • Biblioteca matemática de Xbox proporcionada por el encabezado Xboxmath.h
  • Biblioteca D3DX 9 proporcionada por los archivos DLL D3DX 9
  • Biblioteca matemática D3DX 10 proporcionada a través de los archivos DLL D3DX 10
  • Biblioteca matemática XNA proporcionada por el encabezado xnamath.h en el SDK de DirectX y Xbox 360 XDK

En estas secciones se describen los conceptos básicos de la introducción.

Descargar

La biblioteca DirectXMath se incluye en Windows SDK. Como alternativa, puede descargarlo desde GitHub/Microsoft/DirectXMath. Este sitio también contiene proyectos de ejemplo relacionados.

Requisitos del sistema de Run-Time

La biblioteca directXMath usa instrucciones de procesador especializadas para las operaciones vectoriales cuando están disponibles. Para evitar que un programa genere errores de "excepción de instrucción desconocida", compruebe si hay compatibilidad con el procesador mediante una llamada a XMVerifyCPUSupport antes de usar la biblioteca DirectXMath.

Estos son los requisitos básicos de compatibilidad en tiempo de ejecución de la biblioteca DirectXMath:

  • La compilación predeterminada en una plataforma Windows (x86/x64) requiere compatibilidad con instrucciones SSE/SSE2.
  • La conformidad predeterminada en una plataforma de Windows RT requiere compatibilidad con instrucciones ARM-NEON.
  • La compilación con _XM_NO_INTRINSICS_ definida solo requiere compatibilidad con operaciones de punto flotante estándar.

Nota

Al llamar a XMVerifyCPUSupport, incluya <windows.h> antes de incluir <DirectXMath.h>. Esta es la única función de la biblioteca que requiere cualquier contenido de <windows.h> , por lo que no es necesario incluir <windows.h> en todos los módulos que usen <DirectXMath.h>.

 

Introducción al diseño

La biblioteca DirectXMath es compatible principalmente con el lenguaje de programación C++. La biblioteca se implementa mediante rutinas insertadas en los archivos de encabezado, DirectXMath*.inl, DirectXPackedVector.inl y DirectXCollision.inl. Esta implementación usa intrínsecos del compilador de alto rendimiento.

La biblioteca directXMath proporciona:

  • Una implementación mediante intrínsecos de SSE/SSE2.
  • Una implementación sin intrínsecos.
  • Una implementación que usa intrínsecos arm-NEON.

Dado que la biblioteca se entrega mediante archivos de encabezado, use el código fuente para personalizar y optimizar para su propia aplicación.

Convención de matriz

DirectXMath usa matrices principales de fila, vectores de fila y multiplicación previa. La entrega viene determinada por la versión de función que se usa (RH frente a LH), de lo contrario, la función funciona con coordenadas de vista izquierda o derecha.

Como referencia, Direct3D ha usado históricamente el sistema de coordenadas a la izquierda, las matrices principales de fila, los vectores de fila y la multiplicación previa. Direct3D moderno no tiene un requisito seguro para las coordenadas izquierda frente a derecha, y normalmente los sombreadores HLSL consumen matrices principales de columna de forma predeterminada. Consulte HLSL Matrix Ordering (Ordenación de matrices de HLSL ) para obtener más información.

Uso básico

Para usar las funciones de la biblioteca de DirectXMath, incluya los encabezados DirectXMath.h, DirectXPackedVector.h, DirectXColors.h o DirectXCollision.h. Los encabezados se encuentran en el Kit de desarrollo de software de Windows para aplicaciones de la Tienda Windows.

Directrices de uso de tipos

Los tipos XMVECTOR y XMMATRIX son los caballos de trabajo de la biblioteca DirectXMath. Cada operación consume o genera datos de estos tipos. Trabajar con ellos es clave para usar la biblioteca. Sin embargo, dado que DirectXMath usa los conjuntos de instrucciones SIMD, estos tipos de datos están sujetos a una serie de restricciones. Es fundamental que comprenda estas restricciones si quiere usar las funciones directXMath.

Debería pensar en XMVECTOR como proxy para un registro de hardware SIMD y XMMATRIX como proxy para una agrupación lógica de cuatro registros de hardware SIMD. Estos tipos se anotan para indicar que requieren una alineación de 16 bytes para funcionar correctamente. El compilador los colocará automáticamente en la pila cuando se usen como una variable local o los colocará en el segmento de datos cuando se usen como una variable global. Con las convenciones adecuadas, también se pueden pasar de forma segura como parámetros a una función (consulte Convenciones de llamada para obtener más información).

Sin embargo, las asignaciones del montón son más complicadas. Por lo tanto, debe tener cuidado siempre que use XMVECTOR o XMMATRIX como miembro de una clase o estructura que se va a asignar desde el montón. En Windows x64, todas las asignaciones de montón están alineadas de 16 bytes, pero para Windows x86, solo están alineadas de 8 bytes. Hay opciones para asignar estructuras desde el montón con alineación de 16 bytes (consulte Alineación correcta de asignaciones). En el caso de los programas de C++, puede usar sobrecargas new/delete/delete[]/delete[] (global o específicas de clase) para aplicar una alineación óptima si lo desea.

Nota

Como alternativa a aplicar la alineación en la clase de C++ directamente sobrecargando new/delete, puede usar la expresión pImpl. Si se asegura de que la clase Impl se alinea a través de _aligned_malloc internamente, puede usar libremente los tipos alineados dentro de la implementación interna. Esta es una buena opción cuando la clase "pública" es una clase ref Windows Runtime o está pensada para su uso con std::shared_ptr<>, lo que puede interrumpir la alineación cuidadosa.

 

Sin embargo, a menudo es más fácil y más compacto evitar el uso de XMVECTOR o XMMATRIX directamente en una clase o estructura. En su lugar, use XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4, etc., como miembros de la estructura. Además, puede usar las funciones de carga de vectores y almacenamiento de vectores para mover los datos de forma eficaz a variables locales XMVECTOR o XMMATRIX , realizar cálculos y almacenar los resultados. También hay funciones de streaming (XMVector3TransformStream, XMVector4TransformStream, etc.) que funcionan de forma eficaz en matrices de estos tipos de datos.

Creación de vectores

VECTORES CONSTANTES

Muchas operaciones requieren el uso de constantes en cálculos vectoriales y hay varias maneras de cargar un XMVECTOR con los valores deseados.

  • Si carga una constante escalar en todos los elementos de un XMVECTOR, use XMVectorReplicate o XMVectorReplicateInt.

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • Si usa una constante vectorial con valores fijos diferentes como XMVECTOR, utilice las estructuras XMVECTORF32, XMVECTORU32, XMVECTORI32 o XMVECTORU8 . A continuación, se puede hacer referencia a ellos directamente en cualquier lugar donde pase un valor XMVECTOR .

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

    Nota

    No use listas de inicializadores directamente con XMVECTOR (es decir, XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f }). Este código es ineficaz y no es portátil en todas las plataformas compatibles con DirectXMath.

     

  • DirectXMath incluye varias constantes globales predefinidas que puede usar en el código (g_XMOne, g_XMOne3, g_XMTwo, g_XMOneHalf, g_XMHalfPi, g_XMPi, etc.). Busque en el encabezado DirectXMath.h los valores XMGLOBALCONST .

  • Hay un conjunto de constantes vectoriales para colores RGB comunes (rojo, verde, azul, amarillo, etc.). Para obtener más información sobre estas constantes vectoriales, consulta DirectXColors.h y el espacio de nombres DirectX::Colors.

VECTORES DE VARIABLES

VECTORES DE VECTORES

  • Si crea un vector a partir de otro vector con un componente específico establecido en una variable, puede considerar el uso de funciones de descriptor de acceso vectorial.

    XMVECTOR v2 = XMVectorSetW( v1, fw );
    
  • Si crea un vector a partir de otro vector con un único componente replicado, use XMVectorSplatX, XMVectorSplatY, XMVectorSplatZ y XMVectorSplatW.

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • Si crea un vector a partir de otro vector o par de vectores con componentes reordenados, consulte XMVectorSwizzle y 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 );
    

VECTORES DE MEMORIA

Extracción de componentes de vectores

El procesamiento de SIMD es más eficaz cuando los datos se cargan en los registros SIMD y se procesan completamente antes de extraer los resultados. La conversión entre formas escalares y vectoriales es ineficaz, por lo que se recomienda hacerlo solo cuando sea necesario. Por este motivo, las funciones de la biblioteca DirectXMath que producen un valor escalar se devuelven en una forma vectorial en la que el resultado escalar se replica en el vector resultante (es decir, XMVector2Dot, XMVector3Length, etc.). Sin embargo, cuando necesite valores escalares, estas son algunas opciones sobre cómo hacerlo:

  • Si se calcula una única respuesta escalar, el uso de las funciones de descriptor de acceso vectorial es adecuado:

    float f = XMVectorGetX( v );
    
  • Si es necesario extraer varios componentes del vector, considere la posibilidad de almacenar el vector en una estructura de memoria y volver a leerlo. Por ejemplo:

    XMFLOAT4A t;
    XMStoreFloat4A( &t, v );
    // t.x, t.y, t.z, and t.w can be individually accessed now
    
  • La forma más eficaz de procesamiento de vectores es usar el streaming de memoria a memoria donde los datos de entrada se cargan desde la memoria (mediante funciones de carga de vectores), se procesan completamente en formato SIMD y, a continuación, se escriben en memoria (mediante funciones del almacén de vectores).

Guía de programación de DirectXMath