Книга Фрэнка Луны в целом является отличным введением в Direct 11 API, но, к сожалению, страдает от интенсивного использования устаревшего DirectX SDK, который не рекомендуется для MSDN . Одним из таких аспектов является то, что он на самом деле использует библиотеку xnamath (a.k.a. xboxmath version 2) вместо библиотеки DirectXMath (a.k.a. xboxmath version 3)
См. Книжные рекомендации и Представляем DirectXMath
Я внес ряд изменений при переработке библиотеки под DirectXMath. Во-первых, типы на самом деле находятся в пространствах имен C ++, а не в глобальном пространстве имен. В заголовках вы должны указать полное имя:
#include <DirectXMath.h>
void MyFunction(..., DirectX::CXMMATRIX M);
В ваших исходных файлах cpp вы должны использовать:
#include <DirectXMath.h>
using namespace DirectX;
Еще одно изменение заключалось в том, чтобы категорически не поощрять использование доступа «на элемент» в типах данных XMVECTOR
и XMMATRIX
. Как обсуждалось в Руководство для программистов DirectXMath , эти типы являются запроектированными прокси для типов регистров SIMD, которые не могут быть напрямую доступны для элемента. Вместо этого вы переходите к представлению XMFLOAT4X4
, которое разрешает доступ для каждого элемента, потому что это скалярная структура.
Это видно по тому факту, что операторы, которые вы пытаетесь использовать, определены только для режима без встроенных функций (т. Е. При использовании скалярных операций вместо операций SIMD, таких как SSE, ARM-NEON и т. Д.):
#ifdef _XM_NO_INTRINSICS_
float operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
float& operator() (size_t Row, size_t Column) { return m[Row][Column]; }
#endif
Опять же, по замыслу, этот процесс немного «многословен», потому что он позволяет вам знать, что он не бесплатный. Некоторые люди считают этот аспект DirectXMath немного разочаровывающим, особенно когда они только начинают работу. В этом случае я рекомендую вам взглянуть на оболочку SimpleMath в DirectX Tool Kit . Вы можете использовать типы Vector3
, Vector4
, Matrix
и т. Д., И они свободно конвертируются (через операторы и конструкторы C ++) по мере необходимости в XMVECTOR
и XMMATRIX
. Это не так эффективно, но намного проще для использования.
Конкретная функция, которую вы написали, также немного проблематична. Во-первых, немного странно смешивать параметры XMFLOAT4
и XMMATRIX
. Для соглашения о вызовах «in-register, SIMD-friendly» вы должны использовать:
void XM_CALLCONV ExtractFrustumPlanes(XMVECTOR planes[6], FXMMATRIX M)
Подробнее о причинах см. MSDN .
Если вы хотите просто полностью скалярную математику, используйте не SIMD-типы:
void ExtractFrustumPlanes(XMFLOAT4 planes[6], const XMFLOAT4X4& M)
или, что еще лучше, используйте SimpleMath, чтобы вам не приходилось писать явные преобразования в / из XMVECTOR
или XMMATRIX
using DirectX::SimpleMath;
void ExtractFrustumPlanes(Vector4 planes[6], const Matrix& M)
Обратите внимание, что последняя версия DirectXMath установлена на GitHub и NuGet .