533955f1

Окно программы, рассматриваемой в этой главе



Рисунок 12.8. Окно программы, рассматриваемой в этой главе


Вы можете свободно перемещаться по сцене, используя следующие клавиши:

W/S — передвижение вперед и назад;

A/D — сдвиг влево и вправо;

R/F — полет вверх и вниз;

Стрелки вверх/вниз — наклон камеры;

Стрелки влево/вправо — рыскание камеры;

N/M — вращение камеры.

Реализация примера тривиальна, поскольку вся работа выполняется внутри класса Camera, о котором мы уже говорили. В функции Display мы обрабатываем нажатие клавиш согласно их назначению. Учтите, что мы в начале программы создаем глобальный объект камеры TheCamera. Также обратите внимание, что перемещение камеры синхронизируется по прошедшему с прошлого кадра времени (timeDelta); благодаря этому скорость перемещения не зависит от частоты кадров.

bool Display(float timeDelta) { if(Device) { // // Обновление сцены: перемещение камеры // if(::GetAsyncKeyState('W') & 0x8000f) TheCamera.walk(4.0f * timeDelta);

if(::GetAsyncKeyState('S') & 0x8000f) TheCamera.walk(-4.0f * timeDelta);

if(::GetAsyncKeyState('A') & 0x8000f) TheCamera.strafe(-4.0f * timeDelta);

if(::GetAsyncKeyState('D') & 0x8000f) TheCamera.strafe(4.0f * timeDelta);

if(::GetAsyncKeyState('R') & 0x8000f) TheCamera.fly(4.0f * timeDelta);

if(::GetAsyncKeyState('F') & 0x8000f) TheCamera.fly(-4.0f * timeDelta);

if(::GetAsyncKeyState(VK_UP) & 0x8000f) TheCamera.pitch(1.0f * timeDelta);

if(::GetAsyncKeyState(VK_DOWN) & 0x8000f) TheCamera.pitch(-1.0f * timeDelta);

if(::GetAsyncKeyState(VK_LEFT) & 0x8000f) TheCamera.yaw(-1.0f * timeDelta);

if(::GetAsyncKeyState(VK_RIGHT) & 0x8000f) TheCamera.yaw(1.0f * timeDelta);

if(::GetAsyncKeyState('N') & 0x8000f) TheCamera.roll(1.0f * timeDelta);

if(::GetAsyncKeyState('M') & 0x8000f) TheCamera.roll(-1.0f * timeDelta);

// Обновление матрицы вида согласно новому //местоположению и ориентации камеры D3DXMATRIX V; TheCamera.getViewMatrix(&V); Device->SetTransform(D3DTS_VIEW, &V);

// // Визуализация // Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); Device->BeginScene();

d3d::DrawBasicScene(Device, 1.0f);

Device->EndScene(); Device->Present(0, 0, 0, 0); } return true; }

ПРИМЕЧАНИЕ

Мы добавили в пространство имен d3d новую функцию DrawBasicScene. Эта функция рисует сцену, изображенную на Рисунок  12.8. Мы добавили ее к пространству имен d3d потому что удобно иметь функцию, рисующую стандартную сцену, благодаря чему в следующих примерах мы сможем сосредоточиться на относящемся к изучаемым темам коде и не отвлекаться на код, предназначенный для рисования сцены. Объявление в файле d3dUtility.h выглядит так:

// Внутри функции есть ссылка на файл desert.bmp // Этот файл должен быть в рабочем каталоге приложения bool DrawBasicScene( IDirect3DDevice9* device, // 0 для очистки float scale); // масштаб

Когда эта функция вызывается с корректным указателем на устройство в первый раз, она выполняет инициализацию внутренних данных о геометрии сцены; поэтому рекомендуем вам первый раз вызывать эту функцию из функции Setup. Чтобы очистить внутреннюю геометрию, вызовите эту функцию из процедуры Cleanup, но вместо указателя на устройство передайте null. Поскольку эта функция не выполняет никаких действий, которые бы мы не обсуждали в предыдущих главах, мы предлагаем вам самостоятельно исследовать ее код, который вы найдете в сопроводительных файлах к данной главе. Обратите внимание, что в качестве текстуры функция загружает файл desert.bmp. Этот файл должен находиться в папке приложения.


Содержание раздела