В прошлом шаге мы одновременно применили наш материал, который был создан в "Шаг 16 - Назначим материалы". Также можно присвоить материал непосредственно в 3D Studio MAX и занести его в х-файл. И кроме этого, мы можем нанести текстуры в 3D пакете, как нам вздумается и тоже записать в х-файл. Потом только останется загрузить и отобразить все mesh-и 3D объекта. Что такое mesh, мне словами не объяснить, это нужно видеть. Полностью поймете, когда прочитаете этот и следующий шаг.
Для начала нам нужно создать снова х-файл содержащий в себе не только 3D объект, но и текстуры с материалами. Поэтому заходим в 3D Studio MAX, создаем куб, наносим текстуры и материалы на различные грани (текстуру я нанес на переднюю и заднюю грань куба, а материал расположил сверху). При экспорте в файл 3ds появится запрос: "сохранить координаты текстур?", отвечайте "Да". Конвертируйте в х-формат и незабудьте переписать текстуры которые Вы применили к этому объекту. Берем исходник последнего проекта и немного над ним поработаем.
Добавляем указатели на текстуру и материал в главный класс окна рамки:
LPDIRECT3DTEXTURE8* g_pMeshTextures; // текстура нашего меша DWORD g_dwNumMaterials; // количество материалов в меше D3DMATERIAL8* g_pMeshMaterials; // материал нашего меша
Более подробно об этих структурах см. раздел Справка по DirectX:
Немного подправим нашу функцию LoadMesh():
void CMainWnd::LoadMesh (char *filename) { LPD3DXBUFFER pD3DXMtrlBuffer; D3DXLoadMeshFromX (filename, D3DXMESH_SYSTEMMEM, p_d3d_Device, NULL, &pD3DXMtrlBuffer, &g_dwNumMaterials, &p_d3dx_mesh); D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials]; g_pMeshTextures = new LPDIRECT3DTEXTURE8[g_dwNumMaterials]; for( DWORD i=0; i<g_dwNumMaterials; i++ ) { // Копируем материал g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D; // Устанавливаем цвет подсветки для материала g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse; // Создаем текстуру if( FAILED( D3DXCreateTextureFromFile( p_d3d_Device, d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i] ) ) ) { g_pMeshTextures[i] = NULL; } } }
Для более полной информации см. раздел Справка по DirectX:
Отображение сцены теперь выглядит так:
for( DWORD i=0; i<g_dwNumMaterials; i++ ) { // Устанавливаем материал и текстуру для меша p_d3d_Device->SetMaterial( &g_pMeshMaterials[i] ); p_d3d_Device->SetTexture( 0, g_pMeshTextures[i] ); // Рисуем меш p_d3dx_mesh->DrawSubset( i ); }
Снова заставим вращаться свет, чтобы можно было увидеть сверху материал и сделаем подсветку материала как 0x55555555. Компилируем и запускаем. Должно получиться:
Сделайте вместо куба, скажем сферу, нанесите на нее текстуру, реализуйте код и Вы будете приятно удивлены :)