Программирование графики с использованием Direct3D

         

Функция WrapsWin::LoadMeshes()


Функция LoadMeshes() создает три сетки и присоединяет каждую из них к отдельному фрейму. Фреймы располагаются на расстоянии друг от друга и им назначаются одинаковые атрибуты вращения. Текст функции LoadMeshes() приведен в листинге5.2.

Листинг 5.2. Функция WrapsWin::LoadMeshes()

BOOL WrapsWin::LoadMeshes() { HRESULT r; const D3DVALUE meshscale = D3DVALUE(13); const D3DVALUE meshspacing = D3DVALUE(15); D3DRMLOADRESOURCE resinfo; resinfo.hModule = NULL; resinfo.lpName = MAKEINTRESOURCE(IDR_BOXMESH); resinfo.lpType = "MESH" d3drm->CreateMeshBuilder(&box); r = box->Load(&resinfo, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL); if (r != D3DRM_OK) { TRACE("failed to load internal box mesh\n"); return FALSE; } box->SetPerspective(TRUE); ScaleMesh(box, meshscale - D3DVALUE(2)); LPDIRECT3DRMFRAME boxframe; d3drm->CreateFrame(scene, &boxframe); boxframe->SetPosition(scene, -meshspacing, D3DVALUE(0), D3DVALUE(0)); boxframe->SetRotation(scene, D3DVALUE(0), D3DVALUE(1), D3DVALUE(1), D3DVALUE(.1)); boxframe->AddVisual(box); resinfo.hModule = NULL; resinfo.lpName = MAKEINTRESOURCE(IDR_CYLMESH); resinfo.lpType = "MESH"; d3drm->CreateMeshBuilder(&cyl); cyl->Load(&resinfo, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL); if (r != D3DRM_OK) { TRACE("failed to load internal cylinder mesh\n"); return FALSE; } cyl->SetPerspective(TRUE); ScaleMesh(cyl, meshscale); LPDIRECT3DRMFRAME cylframe; d3drm->CreateFrame(scene, &cylframe); cylframe->SetRotation(scene, D3DVALUE(0), D3DVALUE(1), D3DVALUE(1), D3DVALUE(.1)); cylframe->AddVisual(cyl); resinfo.hModule = NULL; resinfo.lpName = MAKEINTRESOURCE(IDR_SPHEREMESH); resinfo.lpType = "MESH"; d3drm->CreateMeshBuilder(&sphere); sphere->Load(&resinfo, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL); if (r != D3DRM_OK) { TRACE("failed to load internal sphere mesh\n"); return FALSE; } sphere->SetPerspective(TRUE); ScaleMesh(sphere, meshscale); LPDIRECT3DRMFRAME sphereframe; d3drm->CreateFrame(scene, &sphereframe); sphereframe->SetPosition(scene, D3DVALUE(meshspacing), D3DVALUE(0), D3DVALUE(0)); sphereframe->SetRotation(scene, D3DVALUE(0), D3DVALUE(1), D3DVALUE(1), D3DVALUE(.1)); sphereframe->AddVisual(sphere); return TRUE; }

В начале функции объявляется несколько констант, используемых в коде для позиционирования и масштабирования сеток. Затем осуществляется инициализация указателя на интерфейс Direct3DRMMeshBuilder. Функция Load() загружает изображающую куб сетку из ресурсов программы.

Затем для того чтобы разрешить перспективную коррекцию применяется функция SetPerspective(). Если вы установили демонстрационные приложения на свой компьютер, можете закомментировать вызов этой функции и заново скомпилировать приложение Wraps. Перспективная коррекция особенно заметна на сетке куба из-за его больших граней.

Затем выполняется масштабирование сетки с помощью функции ScaleMesh(). Мы уже обсуждали функцию ScaleMesh() в главе 4. ScaleMesh() определена в классе RMWin и предоставляет удобный способ для масштабирования сеток таким образом, чтобы они соответствовали заданному размеру. Константа, используемая для масштабирования куба, слегка изменяется, поскольку сетки кубической формы кажутся больше, чем другие сетки (поскольку куб занимает максимальный объем в минимальном пространстве).

После того, как масштабирование сетки выполнено, функция LoadMeshes() создает фрейм и позиционирует его в соответствии с константой meshspacing. Сетка куба появляется слева от других сеток, поэтому для нее указывается отрицательная координата по оси X. Далее функция SetRotation() назначает фрейму атрибуты вращения. И, в самом конце, с помощью функции AddVisual() интерфейса Direct3DRMFrame к фрейму присоединяется сетка.



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