Следующее отличие рассматриваемой функции заключается в том, что я использую буфер вершин m_pVBUnit вместо буфера m_pVBTile. Это сделано для того, чтобы базовая точка располагалась в центре, о чем я говорил ранее.

Самое большое отличие данной функции — добавление параметра CUnitAnimation. Он сообщает функции откуда она должна брать текстуры. Указатель на класс анимации необходим потому, что именно в нем хранятся используемые для визуализации текстуры.

Я задаю используемую для визуализации текстуру путем передачи в функцию параметра, указывающего ее местоположение во внутреннем массиве класса анимации. В результате отображается базовое изображение подразделения. В следующием вызове функции визуализации изменена позиция в массиве для того, чтобы отображались цвета владельца. Если вы помните, раньше я говорил о том, что цвета владельца хранятся следом за кадром анимации. Данные о цветах накладываются на базовое изображение подразделения, чтобы в результате отображалось изображение подразделения, раскрашенного в цвета его владельца.



- Начало - - Назад - - Вперед -



Функция vDrawUnit()


Теперь, когда у вас есть буфер вершин для подразделения, необходимо место для выполнения визуализации. Здесь выходит на сцену функция рисования подразделения. Она работает точно так же, как функция рисования блока игрового поля, которую я показывал в главе 5, за исключением некоторых добавленных функций. Вот ее код:

void CD3DFramework::vDrawUnit( float fXPos, float fYPos, float fXSize, float fYSize, float fRot, CUnitAnimation *animObj, int iTexture, int iOwner) { D3DXMATRIX matWorld; D3DXMATRIX matRotation; D3DXMATRIX matTranslation; D3DXMATRIX matScale; // Установка значений по умолчанию для // местоположения, масштабирования и вращения D3DXMatrixIdentity(&matTranslation); // Масштабирование блока D3DXMatrixScaling(&matScale, fXSize, fYSize, 1.0f); D3DXMatrixMultiply(&matTranslation,&matTranslation,&matScale); // Вращение блока D3DXMatrixRotationZ(&matRotation, (float)DegToRad(-fRot)); D3DXMatrixMultiply(&matWorld, &matTranslation, &matRotation); // Перемещение блока matWorld._41 = fXPos - 0.5f; // X-Pos matWorld._42 = fYPos + 0.5f; // Y-Pos // Установка матрицы m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld); // Используем буфер вершин блока m_pd3dDevice->SetStreamSource( 0, m_pVBUnit, 0, sizeof(TILEVERTEX)); // Используем фрмат вершин блока m_pd3dDevice->SetFVF(D3DFVF_TILEVERTEX); // Задаем используемую текстуру m_pd3dDevice->SetTexture( 0, animObj->m_Textures[iTexture].m_pTexture); // Отображаем квадрат m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); // Задаем используемую текстуру m_pd3dDevice->SetTexture( 0, animObj->m_Textures[iTexture + iOwner + 1].m_pTexture); // Отображаем квадрат m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); // Разыменовываем текстуру m_pd3dDevice->SetTexture(0, NULL); }

Первое отличие данной функции от ранее рассмотренной vDrawTile() — добавление параметра вращения. Он позволяет вам развернуть двухмерное изображение на любой необходимый угол. Само вращение реализуется перемножением матриц поворота и преобразования. Матрица поворота создается вспомогательной функцией DirectX D3DXMatrixRotationZ().

СОВЕТ
В DirectX угол поворота всегда вычисляется в радианах. Для преобразования угловых величин в радианы я использую макрос DegToRad(). Вам в ваших программах также следует использовать аналогичную функцию или вращение графики и трехмерных объектов будет выполняться неправильно.