Шаг 20 - Загрузка материалов и текстур из Х-файла

В прошлом шаге мы одновременно применили наш материал, который был создан в "Шаг 16 - Назначим материалы". Также можно присвоить материал непосредственно в 3D Studio MAX и занести его в х-файл. И кроме этого, мы можем нанести текстуры в 3D пакете, как нам вздумается и тоже записать в х-файл. Потом только останется загрузить и отобразить все mesh3D объекта. Что такое 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. Компилируем и запускаем. Должно получиться:

Сделайте вместо куба, скажем сферу, нанесите на нее текстуру, реализуйте код и Вы будете приятно удивлены :)


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Хавов Евгений Валерьевич - 2.09.2002