Умножение матриц с DirectXMath

Я сделал учебник http://3dgep.com/introduction-to-directx-11.

В уроке 3 матрицы (проекция, вид и мировая матрица) отправляются в вершинный шейдер и там умножаются.

Я хочу умножить 3 матрицы, чтобы получить только одну, которую я должен отправить вершинному шейдеру.

Когда я пытался умножить их с помощью функции XMMatrixMultiply (), я получил ошибку accessviolation.

XMMatrix wvp=XMMatrixMultiply(g_ProjectionMatrix,XMMatrixMultiply(g_worldmatrix,g_viewmatrix));

0

Решение

Скорее всего, вы попали в AV, потому что не правильно учли выравнивание памяти с вашими переменными. DirectXMath (он же XNAMath) имеет два типа SIMD XMVECTOR а также XMMATRIX который всегда должен быть выровнен по 16 байтов. Они правильно выровнены, если размещены как глобальные переменные, статические переменные или в стеке. Они правильно выровнены в куче выделенной памяти (new или же malloc) только с родными приложениями x64. С 32-битным (x86) или ARM они не по умолчанию. Таким образом, DirectXMath также предоставляет ассортимент типов хранилищ данных и функций загрузки / хранения для обработки этого, не беспокоясь о выравнивании (т.е. XMFLOAT4X4 и XMLoadFloat4x4 / XMStoreFloat4x4 функции). Это описано в Руководстве программиста по MSDN который я настоятельно рекомендую вам потратить время, чтобы прочитать.

Так что вместо использования XMMATRIX в качестве переменной хранения данных вы бы сделали что-то вроде:

XMFLOAT4X4 g_ProjectionMatrix;
XMFLOAT4X4 g_worldMatrix;
XMFLOAT4X4 g_viewMatrix;

XMMATRIX proj = XMLoadFloat4x4( &g_ProjectionMatrix );
XMMATRIX world = XMLoadFloat4x4( &g_worldMatrix );
XMMATRIX view = XMLoadFloat4x4( &g_viewMatrix );
XMMATRIX wvp = XMMatrixMultiply( proj, XMMatrixMultiply( world, view ) );

Хотя это немного многословно, оно более точно соответствует тому, что на самом деле делает оборудование, позволяя вам увидеть возможности избежать накладных расходов на загрузку / хранение и продолжать работать с данными, которые, вероятно, будут храниться в регистрах SIMD дольше.

Все, что сказано, если ваш g_ProjectionMatrix, g_worldmatrix, а также g_viewmatrix переменные действительно глобальны, как показано в этом уроке, и вы попадаете на AV, вы также можете столкнуться с ошибкой компилятора. Какую версию VS вы используете? VS 2008 и VS 2010 немного глючат с w.r.t. к внутренностям. VS 2010 Service Pack 1 немного лучше, чем VS 2010 RTM. VS 2012 и VS 2013 намного лучше. Убедитесь, что вы используете последнее обновление для VS 2012 или VS 2013. Я бы порекомендовал перейти в сообщество VS 2013 (которое также является обновлением VS 4), если у вас нет бюджета на VS 2013 Pro +.

Обратите внимание, что другой вариант здесь заключается в использовании SimpleMath обертка в Набор инструментов DirectX который использует некоторую магию C ++, чтобы сделать наивный математический код более прощающим с такими типами, как Matrix, Vector2, Vector3, Vector4, так далее.

#include "SimpleMath.h"using namespace DirectX::SimpleMath;

Matrix g_ProjectionMatrix;
Matrix g_worldMatrix;
Matrix g_viewMatrix;

Matrix wvp = proj * world * view;
0

Другие решения


По вопросам рекламы [email protected]