После того как вы создали вершинный шейдер, вспомогательные структуры и объявления вершин, вы можете заставить это все работать! Предположим, что имеется базовый меш и четыре целевых меша, уже загруженных в объекты меша.
ID3DXMesh *pBaseMesh;
ID3DXMesh *pMesh1,*pMesh2,*pMesh3,*pMesh4;
Предположим то же самое и для вершинного шейдера и объявления вершин -что вы уже загрузили их и получили их правильные интерфейсы:
IDirect3DVertexShader9 *pShader; IDirect3DVertexDeclaration9 *pDecl;
После загрузки вершинного шейдера вы можете установить его для визуализирования комбинированных мешей, с помощью следующих строк:
pDevice->SetFVF(NULL); //Очистить использование FVF pDevice->SetVertexShader(pShader); //Установить вершинный шейдер pDevice->SetVertexDeclaration(pDecl); //Установить объявления
Чтобы начать рисовать комбинированный меш, вы должны установить потоки вершин, указывающие на буферы вершин меша. Даже если вы не используете четыре комбинируемых меша, вы должны всегда устанавливать потоки вершин; просто используйте буфер вершин базового меша в качестве потока, если у вас менее четырех комбинируемых мешей.
// Получить размер вершины
DWORD VertexStride =D3DXGetFvFvertexSize(pBaseMesh->GetFvF()) ; //Получить указатели на буферы вершин IDirect3DVertexBuffer9 *pBaseVB; IDirect3DVertexBuffer9 *pMesh1vB,*pMesh2vB; IDirect3DVertexBuffer9 *pMesh3vB,*pMesh4vB;
pBaseMesh->GetvertexBuffer(&pBasevB); pMesh1->GetvertexBuffer(&pMesh1vB); pMesh2->GetvertexBuffer(&pMesh2vB) ; pMesh3->GetvertexBuffer(&pMesh3vB); pMesh4->GetvertexBuffer(&pMesh4vB); //Установить потоки вершин
pDevice->SetStreamSource(0,pBasevB,vertexStride) ; pDevice->SetStreamSource(1,pMesh1vB,vertexStride); pDevice->SetStreamSource(2,pMesh2vB,vertexStride); pDevice->SetStreamSource(3,pMesh3vB,vertexStride); pDevice->SetStreamSource(4,pMesh4vB,vertexStride);
Теперь необходимо получить текущие матрицы преобразования мира, вида и проекции вашего 3D устройства. Эти матрицы объединяются, транспонируются и сохраняются в регистры констант вершинного шейдера с с0 до с3. Следующий код замечательно с этим справляется.
//Получить матрицы мира, вида и проекции D3DXMATRIX matWorld,matview,matProj; pDevice->GetTransform(D3DTS_WORLD,&matWorld);
pDeyice->GetTransform(D3DTS_VIEW,&matView); рЕеуісе->ОесТгапзРогтР3ЕТ8_РК0НЕСТІ0М,&тасРго]) ;
//Получить матрицу мир*вид*проекция и установить ее D3DXMATRIX matWVP,•
matWVP =matWor1б *matView *matProj,• D3DXMatrixTranspose(&matWVP,&matWVP);
g_pD3DDeyice->SetVertexShaбerConstantF(0,(f1oat*)&matWVP,4);
Для управления величиной комбинирования для каждого меша просто измените значения, хранимые в регистре с4. Регистр х константы с4 представляет собой величину комбинирования для первого меша и меняется в диапазоне от 0 до 1 (или больше, если вы хотите получить преувеличенные результаты).
Заметание. На самом деле вы не должны вызывать GetTransform для полученияраз-личныхматриц преобразования. Этиматрицы должныхраниться в вашем приложении, по возможности (но необязательно) на глобальномуровне.
Аналогично и для с4.у, с4.ъ, с4.\¥ - каждый меш имеет регистр, хранящий величину комбинирования (у для второго меша, ъ для третьего, \¥ для четвертого).
Пока что установим значения комбинирования в 100 процентов (сохраняя значение 1.0 для каждого значения комбинирования в объекте В3ВХ\ТіСКЖ4)
и сохраним эти значения в константе вершинного шейдера с4, используя функцию
БеїУегІехБпасІегСо^ІапіР.
//Установить величины комбинирования
D3DXVECTOR4 уесВ1епбіпд =D3DXVECTOR4(1.0f,1.0f,1.0f,1.0f) ;
pDevice->SetVertexShaбerConstantF(4,(f1oat*)&vecB1enбing,1) ;
Последнее что нужно сделать, это установить направление света сцены (то же самое, что использовалось в структуре В3ВЬЮИТ9) в константу вершинного шейдера с5. Например, если вы хотите, чтобы свет (расположенный в мировом пространстве) был направлен вниз, вы можете использовать вектор с координатами 0,1,0. (Заметьте, что используете объект В3БХ\ЕСТОЯ4 для сохранения направления вектора, в противоположность объекту В3БХ\ЕСТОЯ3 просто задайте 0 в качестве компоненты \¥.)
//Установить вектор света
D3DXvECTOR3 уесЕідРЛ =D3DXVECTOR4(0.0f,1.0f,0.0f,0.0f) ; pDevice->SetVertexShaбerConstantF(5,(f1oat*)&vecLight,1);
Т. к. вы получаете данные вершин из набора объектов ГО3ВХМе8Іі, вам необходимо установить буфер индексов, потому что все объекты ГО3ВХМе8п используют индексированные списки элементарных объектов. Необходимо установить буфер индексов только базового меша, потому что буферы индексов одинаковы у всех мешей. Следующий код устанавливает буфер индексов базового меша:
//Установить буфер индексов 1В1гесс3В1п6!ехВиггег9 *р1п6^ев ; рВавеМев11-^еМп6ехВиггег(&р1п6^ев); рВеу1се->8еЬ1п61сев(р1п61сев,0);
Наконец, вы можете визуализировать комбинированный меш! Пропуская стандартный код установки текстур и материалов, вы можете визуализировать весь меш, используя следующий код:
// Визуализировать меш
pDevice->DrawIn6exe6Primitive(D3DPT_TRIANGLELIST, \
0,рВавеМевЬ->ОеЬЫитУегЬ1сев(), \ 0,pBaвeMeвh->GetNumFaceв());
Если вы хотите увидеть полнофункциональный пример вершинного шейдера комбинированного морфирования, посмотрите на демонстрационную программу ВкепОМогрпУБ, расположенную на компакт-диске. В главе 11 "Морфируемая лицевая анимация" вы увидите как использовать вершинный шейдер для создания привлекательных лицевых анимаций!
Посмотрите демонстрационные программы
Демонстрационные программы главы 10 (В1епОМогрп и ВЬпОМогрпУБ) иллюстрируют использование материала данной главы для комбинирования набора мешей в один анимированный меш. Обе программы, хотя и похожи внешне (рис. 10.3), используют различные технологии для визуализирования комбинированных морфируемых анимаций.
В ВЬпсгМогрЬ. анимации достигаются блокированием, обновлением и разблокированием буферов вершин различных мешей. В ВкепОМогрпУБ код блокировки, обновления и разблокирования был убран, зато был добавлен код, иллюстрирующий возможности использования мощи вершинных шейдеров при изменении буферов вершин! В любом случае, обе программы не разочаруют вас!
Программы на компакт-диске
В директории главы 10 компакт-диска книги вы обнаружите два проекта, которые иллюстрируют использование комбинированных морфируемых анимаций. Этими проектами являются:
• BlendMoгph. В этом проекте вы увидите, как создавать анимацию, комбинируя морфируемые анимации, непосредственно изменяя вершины мешей. Этот проект расположен в \ВоокСо0е\С11ар10\В1еп0Могр11..

Рис. 10.3. Вводная часть лицевой анимации. Посмотрите, как комбинирование различных мешей может создавать простые анимации лица
• BlendMoгphVS. Посмотрите, как осуществлять комбинированные морфируемые анимации при помощи вершинного шейдера, разработанного в этой главе. Этот проект расположен в \BookCode\Chap10\BlendMorphVS.
Глава 11
⇐Создание вершинных шейдеров комбинированного морфирования || Оглавление || Морфируемая лицевая анимация⇒