Вызрел концептуальный вопрос.
Я начинал с Direct3D, и он меня достал. Как именно, расписывать не буду: все это и так знают.
Решил продолжить изыскания на OpenGL в силу его простоты, платформенной независимости и, главное, преемственности версий.
После долгих раздумий в качестве формата входных данных оставил нехороший .х из Директа (спасибо всем, кто давал мне по форматам советы), прежде всего потому, что иначе у меня не было бы под рукой работающей программы, с которой мог бы сверяться на каждом этапе.
Сделал парсер .х, создал набор базовых классов и, после долгих мучений, запустил таки анимацию.
Последнее мучение было особо суровым: при полном совпадении скелетных данных с моделью в Директе у меня на экран вместо дамочки вылезали сплющенные кракозябры. И вот, вспомнив совет ASD, я транспонировал результирующую матрицу преобразования вершин, прикреплённых к данной кости. Получилось вот что:
for(unsigned i=0;i<m_uiNumBones;i++)
{
pBone=m_pSkeleton->GetBone(i);
pmat=pBone->GetMatOffset();
m_pBoneMatrices[i]=(*pmat);
pmat=pBone->GetMatCombined();
m_pBoneMatrices[i]*=(*pmat);
m_pBoneMatrices[i].transpose();
}
Где MatOffset - обратная матрица преобразования вершин кости, а MatCombined - результирующее положение кости после применения к иерархии анимаций и перемещений модели.
Так вот вопрос: как я понял, матрицы в OpenGL и Direct3D при аналогичном использовании транспонированы по отношению друг к другу. На все ли матрицы это распространяется или только на некоторые? В таком случае в матрице преобразования вектор сдвига надо брать из столбца? Как обычно решают подобную проблему разработчики, пишущие игру сразу для двух API (на выбор пользователя и т.п.)?