Камера
Хоть трехмерный мир почти и бесконечен, но вот возможности ускорителя и процессора далеко не безразмерные. Поэтому приходится оптимизировать изображение на экране. Решение простое. Чтобы все быстро просчитывалось и отрисовывалось с достаточно приемлемым числом кадров, сцена при просчете ограничивается в размерах. То есть отбрасываются те части сцены, которые не попадают внутрь этого ограничения.
В Direct3D роль такого ограничения выполняет камера. То что видно в камеру, то и отрисовывается.
Именно «Матрица вида» и «Матрица проекции» и определяют камеру.
В "Матрице вида" задаётся положение камеры в пространстве и ее направление.
С помощью «Матрицы проекции» определяются размеры ограничивающей пирамиды.
Чтобы правильно заполнить "Матрицу вида" необходимо задать значения трех векторов:
· EyeVector - координаты камеры в пространстве
· LookAtVector – указывает, куда направлен объектив камеры
· UpVector - указывает верх камеры
Задав эти три вектора можно вызывать соответствующую функцию Direct3D, которая правильно заполнит "Матрицу вида".
|
|
Для создания "Матрицы проекции" соответствующей функцией Direct3D необходимо в эту функцию передать следующие значения:
· FieldOfView - поле обзора камеры;
· AspectRatio - соотношение сторон;
· NearViewPlan - передняя отсекающая плоскость;
· FarViewPlan - задняя отсекающая плоскость;
Поле обзора камеры - это угол в радианах, который способен охватить обьектив камеры. Разный угол - и по-разному будет выглядеть сцена.
Соотношение сторон - это то, в каком отношении находятся горизонталь и вертикаль. В обычном телевизоре соотношение сторон 4:3, т.е. если поделить 4 на 3 то получим 1.333333..... Вот это 1.33333 и нужно передавать Direct3D.
Передняя отсекающая плоскость - ближайшая к нам плоскость (вершина пирамиды). Задается значением по координате Z.
Задняя отсекающая плоскость - основание пирамиды.
Таким образом, задав три вектора и четыре параметра и вызвав соответствующие функции Direct3D можно получить готовые матрицы для использования. Камера готова.
Для настройки параметров камеры используется функция D3DXMatrixPerspectiveFovLH, которая получает матрицу проекций и в общем виде выглядит следующим образом:
D3DXMATRIX* D3DXMatrixPerspectiveFovLH(D3DXMATRIX* pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf);* pOut - указатель на структуру D3DXMATRIX, через которую мы получим результат работы;
* fovy – угол обзора;
* Aspect – соотношение сторон;
* zn – расстояние до ближней плоскости отсечения. Все, что находиться ближе считается невидимым;
* zf – расстояние до дальней плоскости отсечения. Все, что находиться дальше считается невидимым.
На рисунке ниже графически показаны параметры этой функции. В точке P находиться камера и из этой точки мы смотрим на мир. Все, что ближе zn или дальше zf, мы видеть не можем. Угол между двумя линиями взора направленными под углом вниз и вверх – это и есть значение fovy.
|
|
В нашем приложении для того, чтобы воспользоваться функцией D3DXMatrixPerspectiveFovLH() создадим переменную типа D3DXMATRIX и в неё запишем результат работы функции:
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,D3DX_PI/4.0f,Aspect, 0.1f,1000.0f);
Теперь необходимо установить созданную матрицу устройству IDirect3DDevice. Для этого используется метод SetTransform:
HRESULT SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix);State - тип матрицы. Аргумент указывает, какая матрица задаётся. Значения могут быть следующими:
D3DTS_WORLD (матрица преобразования в мировое координатное пространство);
D3DTS_VIEW (матрица преобразования в пространство камеры);
D3DTS_PROJECTION (матрица проекции из пространства камеры на плоскость).
pMatrix – Указатель на матрицу.
Теперь можно указать матрицы преобразования:
dev->SetTransform(D3DTS_WORLD, &matWorld);dev->SetTransform(D3DTS_VIEW, &matCam);dev->SetTransform(D3DTS_PROJECTION, &matProj);Указатель на устройство у нас сохранен в переменной ppiD3DDevice9, а значит, вызов функции будет выглядеть следующим образом:
(*ppiD3DDevice9)->SetTransform(D3DTS_PROJECTION, &matProjection);Теперь функцию инициализации можно считать завершенной. Попробуйте запустить программу и убедиться, что она работает.