Не совсем.Это немного тоньше, чем это.Позвольте мне сначала пройтись по основам преобразований.
В DirectX и трехмерной графике в целом преобразования обычно представлены аффинной матрицей преобразования 4x4, которая выполняет три последовательных геометрических преобразования: одно из локального пространства в мировое пространство (матрица мира), одна из мирового пространства в пространство, ориентированное на камеру (матрица вида), и одна из пространства, ориентированного на камеру, в "пространство однородного клипа" (матрица проекции).Как правило, вы услышите это как матрицу WVP ( W orld- V iew- P rojection).
Матрица одиночного преобразования создается путем умножения каждой из отдельных матриц преобразования, из которых она состоит.Этот процесс умножения не является коммутативным, то есть матрица AB не совпадает с матрицей BA.В контексте преобразований AB применяет преобразование A, а затем преобразование B, тогда как BA применяет преобразование B и затем преобразование A. Если A - это поворот на 45 градусов вокруг Z, а b - это перевод 3 единиц вдоль X, AB будет вращатьсяобъект на 45 градусов и разместите его на 3 единицы вправо, тогда как BA сместит объект на 3 единицы вправо и повернет его на 45 градусов, как если бы он был соединен с исходным положением с помощью стержня.На рисунке ниже это показано графически.
Теперь, когда мы рассмотрели основы, давайте перейдем к реальному коду.
Рассматривая это, я вижу, что ваше первоначальное предположение о проблеме было и правильным, и неправильным - вы выяснили, в чем проблема, но неправильно истолковали причину.
Первая серьезная проблема - ваша геометрия полностью указана в мировом пространстве.Это нормально, если геометрия никогда не будет двигаться, но суть этого вопроса в том, чтобы заставить указанную геометрию двигаться, поэтому ...
Чтобы исправить это, постройте свою форму самым простым способом:по центру вокруг начала координат со сторонами длины 1. Это меняет четыре угла на следующие, предполагая, что + X направо, + Y вверх и + Z вне (в экран): (-0.5, 0.5, 0), (0,5, 0,5, 0), (-0,5, -0,5, 0), (0,5, -0,5, 0).Они представляют верхний левый, верхний правый, нижний левый и нижний правый углы соответственно.
Это также позволяет вам создать буфер вершин один раз в конструкторе, и вам больше никогда не потребуется его обновлять, даже еслиразмер изображения изменяется во время выполнения.
Во-вторых, поскольку исходная спецификация геометрии уже была в мировом пространстве, нам не требовалась матрица реального мира.Теперь, когда наша геометрия представляет собой единичный квадрат вокруг локального происхождения, мы делаем это.Чтобы получить изображение того же размера, что и исходное растровое изображение, мы создаем масштабную матрицу, которая масштабируется на m_bitmapWidth
по оси X и m_bitmapHeight
по оси Y.Затем мы умножаем его на матрицу вращения вокруг оси Z, чтобы вращать его, и, наконец, умножаем его на матрицу перевода, чтобы переместить его в positionX
и positionY
.Мы можем переписать UpdateBuffers
следующим образом:
bool BitmapClass::UpdateBuffers(int positionX, int positionY, float rotationAngle)
{
D3DXMATRIX scaling, rotation, translation, worldMatrix;
// If the position we are rendering this bitmap to has not changed,
// don't update the world matrix since it currently has the correct
// parameters.
if((positionX == m_previousPosX) && (positionY == m_previousPosY))
{
return true;
}
// If it has changed then update the position it is being rendered to.
m_previousPosX = positionX;
m_previousPosY = positionY;
// scale, rotate, and translate our unit square
D3DXMatrixScaling(&scaling, m_bitmapWidth, m_bitmapHeight, 1);
D3DXMatrixRotationZ(&rotation, rotationAngle);
D3DXMatrixTranslation(&translation, positionX, positionY, 0);
//Now concatenate all the transformations together,
D3DXMatrixMultiply(&worldMatrix, &scaling, &rotation);
D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &translation);
// And tell D3D this is our new world matrix.
m_D3D->SetWorldMatrix(worldMatrix);
return true;
}
Окончательное редактирование - удалить вызов на UpdateBuffers
в BitmapClass::Render
и выполнить вызов до вызова GetWorldMatrix
.Это гарантирует, что процесс рендеринга использует правильную матрицу преобразования.