РАПИДОГРАФ ФИОЛЕТОВОГО КВАРЦА


Новости
Статьи
Файлы
О себе
Гостевая







BASS Photo Gallery Dumpy home page




E-mail

 

DirectX 8 - Урок 4. Работа с моделями

Как вы помните, на протяжении всех трех наших предыдущих уроков, мне приходилось для демонстрации использовать простые фигуры, такие как треугольник и квадрат. Выглядело это достаточно красиво, но было очень не солидно, и поэтому я решил кардинально исправить это положение. Покопавшись немного в первоисточниках, я с радостью обнаружил, что в DirectX SDK есть много красивых моделей, которые хранятся в файлах с расширением *.X. Так и приходит на ум ассоциация с известным сериалом .... - ну вы поняли с каким. Так что же они собой представляют?

Вы знаете из нашего первого примера, что каждый объект или модель состоит из набора треугольников, которым соответствует конечное множество вершин. В *.X файле хранятся не только эти данные, но и названия файлов текстур, параметры материалов, анимация и многое другое. Но сейчас для нас главное получит список вершин и образуемых ими список треугольников, чтобы нарисовать модель. Для этого в Direct3D есть класс модели ID3DXMesh (дословно Mesh означает "сетка").

// Функция LoadMesh() загружает модель
int LoadMesh(void)
{
    // Загружаем модель из файла
    if(FAILED(D3DXLoadMeshFromX("bigship1.x", D3DXMESH_SYSTEMMEM,
        d3d_device,NULL,NULL,
        NULL,&d3dx_mesh))) return 0;
    // Вычисляем количество байт на одну вершину модели
    if(d3dx_mesh->GetFVF()&D3DFVF_XYZ) 
        i_size_of_mesh_vertex += sizeof(float)*3;
    if(d3dx_mesh->GetFVF()&D3DFVF_NORMAL) 
        i_size_of_mesh_vertex += sizeof(float)*3;
    if(d3dx_mesh->GetFVF()&D3DFVF_TEX1) 
        i_size_of_mesh_vertex += sizeof(float)*2;

    // Получаем указатели на буфер вершин и индексный буфер
    d3dx_mesh->GetVertexBuffer(&d3d_vb);
    d3dx_mesh->GetIndexBuffer(&d3d_ib);
  
  // Возращаем OK
    return 1;
}

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

Ну если с буфером вершин все ясно и понятно, и мы знаем, зачем он нужен, то причем тут еще какой-то индексный буфер? А все дело в том, что крайне неэффективно хранить в буфере вершин информацию о всех треугольниках и их вершинах. Если взять к примеру куб, то видно, что мы вынуждены дублировать каждую его вершину по несколько раз. Подсчитаем: 12 треугольников * 3 вершины на каждый треугольник, получаем 36 вершины, а их на самом деле всего 8. А представьте, если в нашей модели 10000 треугольников? Вот так-то!

Для этого и появилась необходимость в дополнительном индексном буфере. В этом буфере, как понятно из названия, хранятся только индексы вершин из соответствующего буфера, которые образуют треугольники. А так как размер одного индекса составляет всего два байта, налицо явная экономия пространства и времени (простите, я хотел сказать - памяти и времени обработки). Немного изменим функцию прорисовки сцены.

// Прорисовка сцены
d3d_device->SetVertexShader(d3d_vertex_shader);
d3d_device->SetStreamSource(0,d3d_vb,i_size_of_mesh_vertex);
d3d_device->SetIndices(d3d_ib,0);
d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
                                 0,d3dx_mesh->GetNumVertices(),
                                 0,d3dx_mesh->GetNumFaces());

Функцией SetStreamSource наш буфер вершин назначается в нулевой поток, а функцией SetIndices текущим индексным буфером становится d3d_ib. Прорисовка сцены теперь выполняется с помощью DrawIndexedPrimitive, к аргументам которой добавились начальный номер индекса и общее количество вершин d3dx_mesh->GetNumVertices().

Рисунок 1. Модель космического коробля

В итоге мы получили очень красивую модель космического коробля. Исходный текст этой программы и exe-файл вы можете взять здесь. Также в архиве вы найдете еще два файла с моделями: дельфин и биплан. Попробуйте их, но не забудьте в функции SetMatrices поменять масштабный коэффициент f_scale на другой, т.к. все модели разного масштаба.


Взято с DirectX Design

Все права проигнорированны © 2002, StasH
Сайт создан в системе uCoz