Функция LoadMeshes() отвечает за загрузку сеток из указанного файла. Она должна проверить, что каждая сетка содержит одно и тоже количество вершин, а также извлечь и сохранить данные вершин. По этой причине код функции получился весьма длинным (и уродливым). Вы можете взглянуть на него в листинге 8.3.
Листинг 8.3. Функция MorphWin::LoadMeshes() | |
BOOL MorphWin::LoadMeshes(const CString& filename) { for (DWORD i = 0; i < nummorphtargets; i++) delete [] morphmeshdata[i]; nummorphtargets = 0;
if (morphmesh) { morphmesh->Release(); morphmesh = 0; } BOOL load_ok = TRUE; for (i = 0; i <MAXMORPHTARGETS && load_ok; i++) { CString msg; HRESULT r; LPDIRECT3DRMMESHBUILDER builder; d3drm->CreateMeshBuilder(&builder); r = builder->Load((void*)(LPCTSTR)filename, (void*)morphmeshname[i], D3DRMLOAD_FROMFILE | D3DRMLOAD_BYNAME, NULL, NULL); load_ok = r == D3DRM_OK; if (r == D3DRMERR_FILENOTFOUND) { TRACE("file not found\n"); CString msg = filename + ": file not found"; AfxMessageBox(msg); morphing = FALSE; } if (!load_ok) goto nomoremeshes; D3DVALUE scale; if (i == 0) scale = ScaleMesh(builder, D3DVALUE(25)); else builder->Scale(scale, scale, scale); builder->SetQuality(D3DRMRENDER_FLAT); LPDIRECT3DRMMESH mesh; builder->CreateMesh(&mesh); unsigned vcount, fcount; DWORD ds; mesh->GetGroup(0, &vcount, &fcount, 0, &ds, 0); if (i == 0) nummorphvertices = vcount; else if (vcount != nummorphvertices && load_ok) { TRACE("invalid vertex count\n"); AfxMessageBox("Invalid vertex count"); morphing = FALSE; return FALSE; } morphmeshdata[i] = new D3DRMVERTEX[nummorphvertices]; r = mesh->GetVertices(0, 0, nummorphvertices, morphmeshdata[i]); if (r != D3DRM_OK) TRACE("mesh->GetVertices() failed\n"); msg.Format("Mesh %d - %d vertices, %d faces", i+1, vcount, fcount); SetWindowText(msg); if (i == 0) morphmesh = mesh; else { mesh->Release(); mesh = 0; } nomoremeshes: builder->Release(); builder = 0; } nummorphtargets = i - 1; morphing = TRUE; return TRUE; } |
Данная функция вызывается при загрузке новой последовательности трансформаций, а значит в момент обращения к функции LoadMeshes() уже может существовать загруженная ранее последовательность. Поэтому первое, что должна сделать функция, — освободить любые выделенные ранее ресурсы.
Затем функция в цикле пытается загрузить 26 шагов трансформации. Цикл прекращается если очередная сетка не будет найдена, либо если обнаруженная сетка содержит другое количество вершин. Когда сетка загружена, функция GetVertices() интерфейса Direct3DRMMesh извлекает данные вершин сетки. Кроме того, в заголовке окна отображается новое сообщение. Функция также инициализирует переменные класса nummorphvertices и nummorphtargets.