Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DirectX. Продвинутая Анимация (2004) [rus].pdf
Скачиваний:
335
Добавлен:
16.08.2013
Размер:
8.39 Mб
Скачать

110

Глава3

Загрузка мешей с использованием D3DX

Библиотека D3DX определяет удобный объект ID3DXMesh, который хранит и визуализирует трехмерные меши. Кроме этого вы можете использовать собственные специализированные контейнеры для хранения мешей, которые, я думаю, разумно использовать с ID3DXMesh. Этот объект я буду использовать до окончания этой главы (за исключением использования удобного объекта ID3DXSkinMesh, о котором я расскажу позже).

Самым быстрым способом загрузки данных меша при помощи D3DX является использование функций D3DXLoadMeshFromX и D3DXLoadMeshFromXof. Оба этих меша берут данные, хранимые в .X файле, и преобразуют их в объект ID3DXMesh. D3DXLoadMeshFromX сразу загружает весь файл .X (объединяя все меши в один), в то время как D3DXLoadMeshFromXof загружает один меш, указанный объектом IDirectXFileData.

Функция D3DXLoadMeshFromX имеет в качестве параметров имя загружаемого файла, некоторые флаги для контролирования загрузки, указатель на 3D устройство, указатели на буферы, содержащие данные материалов и различные указатели на данные, которые вы можете пока проигнорировать. Посмотрите на прототип функции D3DXLoadMeshFromX.

HRESULT D3DXLoadMeshFromX(

LPSTR pFilename, // Имя загружаемого .X файла DWORD Options, // Опции загрузки

LPDIRECT3DDEVICE9 pDevice, // указатель на трехмерное устройство LPD3DXBUFFER* ppAdjacency, // Установить в NULL

LPD3DXBUFFER* ppMaterials, // Буфер для материалов

LPD3DXBUFFER* ppEffectInstances, // Здесь не используется - NULL PDWORD pNumMaterials, // # загруженных материалов

LPD3DXMESH* ppMesh); // Указатель на интерфейс меша

Приведенные комментарии являются самоописательными, так что сразу перейдем к рассмотрению использования функции D3DXLoadMeshFromX. Для начала вам необходимо создать экземпляр объекта ID3DXMesh.

ID3DXMesh *Mesh = NULL;

Далее предположим, вы хотите загрузить файл .X, называемый "test.x". Все просто - вам необходимо указать имя файла при вызове функции D3DXLoadMeshFromX ... но подождите! А как же параметр Options? Вы используете его, чтобы сказать D3DX как загружать меш - в системную или видео память, использовать память только для записи и так далее. Для каждой опции есть флаг. В таблице 3.3 приведен список основных макросов.

Использованиеформатафайла.X

///

 

Таблица 3.3. Флаги D3DXLoadMeshFromX

 

 

Макрос

Описание

 

 

D3DXMESH_32BIT

Использовать 32-битные индексы (не всегда

 

поддерживается)

 

 

D3DXMESH_USEHWONLY

Использовать только аппаратную обработку. Использовать

 

только те устройства, которые точно поддерживают

 

аппаратное ускорение.

 

 

D3DXMESH_SYSTEMMEM

Хранить меш в системной памяти

 

 

D3DXMESH_WRITEONLY

Установить данные меша только для записи, позволяя

 

Direct3D находить лучшие расположения для хранения

 

данных меша (обычно в видео памяти)

 

 

D3DXMESH_DYNAMIC

Использовать динамические буферы (для мешей,

 

изменяющихся со временем)

 

 

D3DXMESH_SOFTWAREPROCESSING

Использовать программную обработку вершин, используемую

 

вместо движка аппаратного преобразования и освещения

 

 

Из таблицы 3.3 видно, что опций загрузки мешей на самом деле не так уж и много. Вообще-то, я бы рекомендовал вам использовать только D3DXMESH_SYSTEMMEM или D3DXMESH_WRITEONLY. Первая опция D3DXMESH_SYSTEMMEM вынуждает храниться данным вашего меша в системной памяти, что ускоряет доступ к его данным для записи и чтения.

Задание флага D3DXMESH_DYNAMIC означает, что вы собираетесь периодически изменять данные меша. Лучше всего устанавливать этот флаг, если вы собираетесь периодически изменять данные меша (вершины) во время выполнения.

Если вам необходима скорость, то я предлагаю использовать флаг 3DXMESH_WRITEONLY, который говорит D3DX использовать память, из которой нельзя читать. В большинстве случаев это означает использование видеопамяти, потому что она обычно (но не всегда) только для записи. Если вы не будете читать данные вершин меша, тогда используйте этот флаг.

Совет.Если вы не используете системную память или память только для записи, что остается использовать?Простозадайте вкачестве параметра Options 0 при вызове D3DXLoadMeshFromX,ивсебудетнормально.

Возвращаясь к параметрам D3DXLoadMeshFromX, вы найдете указатель на интерфейс 3D устройства. Никаких проблем - хотя бы одно должно быть у вас в проекте! Следующий параметр - указатель на ID3DXBUFFER, ppAdjacency. Установите его в NULL, мы не будем его тут использовать.

112

Глава3

Следующие три параметра ppMaterials, ppEffectInstance и pNumMaterials содержат информацию о материале, такую как значения цветов, название текстуры и данные эффектов. Если вы используете DirectX 8, вы можете безопасно удалить ссылку ppEffectlnstance - она не существует в той версии. Если вы используте DirectX 9, вы можете установить ppEffectlnstance в NULL, потому что вам не нужна никакая информация об эффектах.

Указатель ppMaterials указывает на интерфейс ID3DXBuffer, который является простым контейнером данных. pNumMaterials - это указатель на переменную DWORD, которая будет содержать количество материалов в загруженном меше. Вы узнаете, как использовать информацию о материалах немного позже.

Завершает список параметров D3DXLoadMeshFromX указатель на объект ID3DXMesh - ppMesh. Этот интерфейс вы предоставляете для хранения данных загруженного меша. Вот и все! Теперь объединим все это в работающий пример загрузки меша.

Загрузите меш, названный "test.x", используя память для записи. После создания указателя объекта меша вам необходимо создать экземпляр объекта ID3DXBuffer для хранения данных материала и переменную DWORD для хранения количества материалов.

ID3DXBuffer *pMaterials = NULL;

DWORD NumMaterials;

После этого вызываем D3DXLoadMeshFromX.

// pDevice = указатель на правильный объект IDirect3DDevice9 D3DXLoadMeshFromX("test.x", D3DXMESH_WRITEONLY, pDevice, \

NULL, &pMaterials, NULL, &NumMaterials, &Mesh);

Замечательно! Если все прошло, как и было задумано, D3DXLoadMeshFromX вернет код успешного завершения, и ваш меш загрузится в интерфейс ID3DXMesh! Конечно, все меши, содержащиеся в файле, были объединены в один меш, но как насчет тех случаев, когда необходимо получить доступ к каждому отдельно определенному мешу в файле?

Вот здесь то и появляется D3DXLoadMeshFromXof. Вы можете использовать D3DXLoadMeshFromXof в сочетании с вашим анализатором .X для загрузки данных меша из перечисленного объекта Mesh. Посмотрите на прототип функции D3DXLoadMeshFromXof.

HRESULT D3DXLoadMeshFromXof(

LPDIRECTXFILEDATA pXofObjMesh,

DWORD Options,

Использованиеформата файла .X

LPD3DXBUFFER* ppMaterials,

LPD3DXBUFFER* ppEffectInstances,

PDWORD pNumMaterials,

LPD3DXMESH* ppMesh);

Подождите-ка! D3DXLoadMeshFromXof выглядит практически так же как D3DXLoadMeshFromX! Единственным отличием является первый параметр, вместо указания имени загружаемого .X файла, D3DXLoadMeshFromXof использует указатель на объект IDirectXFileData. Задав указатель на текущий перечисляемый объект IDirectXFileData, D3DX загрузит все необходимые данные меша! И так как оставшиеся параметры совпадают с D3DXLoadMeshFromX, у вас не возникнет трудностей с использованием D3DXLoadMeshFromXof в вашем классе анализатора .X!

Остановимся на этом, потому что вы увидите, как использовать D3DXLoadMeshFromXof в вашем классе анализатора далее в этой главе, в разделе "Загрузка мешей, используя анализатор .X ".

Независимо от используемой функции для загрузки данных меша (D3DXLoadMeshFromX или D3DXLoadMeshFromXof) все, что вам остается сделать после загрузки меша в объект ID3DXMesh - это обработать информацию о материалах.

Для обработки информации о материалах вам необходимо получить указатель на буфер данных ID3DXBuffer (используемый при вызове D3DXLoadMeshFromX или D3DXLoadMeshFromXof), и преобразовать его к типу D3DXMATERIAL. После этого обработать все материалы, используя количество материалов сохраненных в NumMaterials. После этого вам необходимо создать массив структур D3DMATERIAL9 и интерфейсов IDirect3DTexture9 для хранения данных материалов меша. Используйте следующий код для обработки информации материалов:

//Объекты для хранения данных материалов и текстур D3DMATERIAL9 *Materials = NULL;

IDirect3DTexture9 *Textures = NULL;

//Получить указатель на данные материалов D3DXMATERIAL *pMat;

pMat = (D3DXMATERIAL*)pMaterials->GetBufferPointer() ;

//Выделить пространство для хранения материала if(NumMaterials) {

//Loading Meshes from .X

Materials = new D3DMATERIAL9[NumMaterials];

Textures = new IDirect3DTexture9*[NumMaterials];

// Просмотреть все загруженные материалы for(DWORD i=0;i<NumMaterials;i++) {

// Скопировать информацию о материале

Соседние файлы в предмете Программирование на C++