2015-01-07 4 views
0

Я сделал учебник http://3dgep.com/introduction-to-directx-11.Матричное умножение с DirectXMath

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

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

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

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

ответ

0

Возможно, вы попали в AV, потому что вы неправильно учли выравнивание памяти с вашими переменными. DirectXMath (aka 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 немного лучше, чем RTM VS 2010. VS 2012 и VS 2013 намного лучше. Убедитесь, что вы используете последнее обновление для VS 2012 или VS 2013. Я бы рекомендовал перейти к сообществу VS 2013 (который также является VS Update 4), если у вас нет бюджета для VS 2013 Pro +.

Обратите внимание, что другой вариант здесь, чтобы использовать SimpleMath обертки в DirectX Tool Kit, который использует некоторые 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

Спасибо за ваш великий ответ. Я попробую это завтра. Я использую последнее обновление VS 2012 на win7. – CrazySocke

Смежные вопросы