Введение в программирование трехмерных игр с DX9

       

Окно программы XFile



Рисунок 11.1. Окно программы XFile


В данном примере используются следующие глобальные переменные:

ID3DXMesh* Mesh = 0; std::vector<D3DMATERIAL9> Mtrls(0); std::vector<IDirect3DTexture9*> Textures(0);

Здесь мы объявляем объект ID3DXMesh, который будет использоваться для хранения данных сетки, загружаемых из X-файла. Мы также объявляем векторы материалов и текстур, которые будут хранить используемые в сетке материалы и текстуры.

Начнем с реализации нашей стандартной функции Setup. Сначала мы загружаем X-файл:

bool Setup() { HRESULT hr = 0;

// // Загрузка данных из X-файла // ID3DXBuffer* adjBuffer = 0; ID3DXBuffer* mtrlBuffer = 0; DWORD numMtrls = 0;

hr = D3DXLoadMeshFromX( "bigship1.x", D3DXMESH_MANAGED, Device, &adjBuffer, &mtrlBuffer, 0, &numMtrls, &Mesh);

if(FAILED(hr)) { ::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0); return false; }

После того, как данные из X-файла загружены мы должны перебрать все элементы массива D3DXMATERIAL и загрузить текстуры, на которые ссылается сетка:

// // Извлечение материалов и загрузка текстур //

if(mtrlBuffer != 0 && numMtrls != 0) { D3DXMATERIAL* mtrls=(D3DXMATERIAL*)mtrlBuffer-> GetBufferPointer();

for(int i = 0; i < numMtrls; i++) { // При загрузке в свойстве MatD3D не устанавливается // значение для фонового света, поэтому установим его сейчас mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;

// Сохраняем i-ый материал Mtrls.push_back(mtrls[i].MatD3D);

// Проверяем, связана ли с i-ым материалом текстура if( mtrls[i].pTextureFilename != 0 ) { // Да, загружаем текстуру для i-ой подгруппы IDirect3DTexture9* tex = 0; D3DXCreateTextureFromFile( Device, mtrls[i].pTextureFilename, &tex);

// Сохраняем загруженную текстуру Textures.push_back(tex); } else { // Нет текстуры для i-ой подгруппы Textures.push_back(0); } } } d3d::Release<ID3DXBuffer*>(mtrlBuffer); // закончили работу с буфером . . // Пропущен код, не относящийся к теме данной главы . // (т.е.
установка освещения, матриц вида и проекции и т.д.) . return true; } // конец функции Setup()

В функции Display мы в каждом кадре слегка разворачиваем сетку, чтобы она вращалась. Сетка визуализируется с помощью простого цикла, поскольку ее подгруппам присвоены номера, идущие в порядке 0, 1, 2, ..., n– 1, где n — это количество подгрупп:

bool Display(float timeDelta) { if(Device) { // // Обновление: поворот сетки //

static float y = 0.0f; D3DXMATRIX yRot; D3DXMatrixRotationY(&yRot, y); y += timeDelta;

if( y >= 6.28f ) y = 0.0f;

D3DXMATRIX World = yRot;

Device->SetTransform(D3DTS_WORLD, &World);

// // Визуализация //

Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);

Device->BeginScene();

for(int i = 0; i < Mtrls.size(); i++) { Device->SetMaterial(&Mtrls[i]); Device->SetTexture(0, Textures[i]); Mesh->DrawSubset(i); }

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


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