Я пытаюсь сделать некоторые 3D-вещи в DirectX (я мигрирую из OpenGL), и я столкнулся с проблемой.
Я хочу получить доступ к значениям XMMATRIX и, глядя на документацию Microsoft, должен быть оператор ():
float& operator ()(
size_t Row,
size_t Column
);
Поэтому я попытался использовать как таковой:
XMMATRIX i = XMMatrixIdentity();
float j = i(0,0);
Но Intellisense дает мне ошибку:
IntelliSense: вызов объекта типа класса без соответствующего оператора () или функций преобразования в указатель на тип функции.
Если я игнорирую Intellisense и все равно компилирую, я получаю ошибку времени компиляции:
ошибка C2064: термин не оценивает функцию, принимающую 2 аргумента
Кто-нибудь имеет представление о том, почему это происходит? Или другой способ доступа к элементам Матрицы?
Спасибо за ваше время.
Постскриптум Я создаю C ++ / DirectX Modern UI App для Windows 8, если эта информация поможет вообще.
Проверьте эта ссылка MSDN и вы увидите, что это зависит от того, какой математический заголовок DirectX или XNA у вас есть, и определения препроцессора, действовавшие в то время. По умолчанию и по причинам оптимизации матрицы и векторные структуры будут реализованы с использованием SSE и встроенных функций, что затрудняет и удорожает доступ к строкам / столбцам.
Попробуйте определить _XM_NO_INTRINSICS_
в директиве препроцессора записи C ++ свойств вашего проекта, или #define _XM_NO_INTRINSICS_
до тебя #include
любые заголовки DirectX.
Этот отрывок из DirectXMath.h
на моей системе Windows 8 VS2012 показывает, почему вы получаете эту ошибку:
struct XMMATRIX
{
// ... code removed for clarity
#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
// ... code removed for clarity
};
Индивидуальный элемент доступа для XMVECTOR
а также XMMATRIX
очень неэффективен из-за базового набора инструкций SIMD, поэтому библиотека DirectXMath не поддерживает его через методы-члены. Есть несколько способов добиться этого в зависимости от ваших потребностей.
Если вам просто нужен элемент (0,0), вы можете использовать:
float j = XMVectorGetX( i.r[0] );
Если вы собираетесь получить доступ к большинству или всем отдельным элементам XMMATRIX, лучшим решением будет выгрузить его в XMFLOAT4X4
:
XMFLOAT4X4 tmp;
XMStoreFloat4x4( &tmp, i );
float j = tmp.m[0][0]; // or float j = tmp._11
Я отправлю сообщение об ошибке, потому что оператор (), упомянутый в MSDN, на самом деле является «XNAMath», а не «DirectXMath». Увидеть этот блог для некоторого фона.
Если вы находите DirectXMath слишком сложным для ваших нужд, вы можете рассмотреть возможность использования SimpleMath в Набор инструментов DirectX.
Я обнаружил, что это работает, я также основал свой код на том же учебнике по отбору лучей и перехожу с xnamath на directxmath.
Это выберет правильные значения из матрицы без необходимости отключения SSE Intrinsics.
«Проекция» — это XMMATRIX, содержащий матрицу вида с камеры.
XMVECTOR xv = projection.r[0];
XMVECTOR yv = projection.r[1];
PRVecX = ((( 2.0f * mouseX) / Window::ClientWidth) - 1 ) / XMVectorGetX(xv);
PRVecY = -((( 2.0f * mouseY) / Window::ClientHeight) - 1 ) / XMVectorGetY(yv);
Отключение встроенных функций с помощью плохой идея, потому что это сильно замедляет вашу программу. По возможности конвертируйте ваш код, чтобы правильно загружать и хранить внутренние значения, как указано выше.
Добавьте #define _XM_NO_INTRINSICS_ в начало файла。
#include <windows.h>
#define _XM_NO_INTRINSICS_//must before #include <DirectXMath.h>
#include <DirectXMath.h>
#include <iostream>
Ты можешь попробовать:
XMMATRIX i = XMMatrixIdentity();
float j = i.r[0].m128_f32[0];