netlib.narod.ru< Назад | Оглавление | Далее >

5.5. Пример приложения: освещенная пирамида

Пример приложения из этой главы создает сцену, показанную на рис. 5.7. Он показывает как задать нормали вершин, как создать материал и как создать и активизировать источник направленного света. Обратите внимание, что в этом примере мы не пользуемся функциями и объявлениями для материала и источника света из файлов d3dUtility.h/cpp потому что хотим сперва показать вам как можно всю работу выполнить вручную. Однако в остальных примерах из этой книги мы будем пользоваться вспомогательными функциями для задания материалов и источников света.


Рис. 5.7. Окно приложения LitPyramid

Рис. 5.7. Окно приложения LitPyramid


Вот действия, которые необходимо выполнить, чтобы добавить к сцене источник света:

  1. Разрешить освещение.

  2. Создать материал для каждого объекта и задать используемый материал перед визуализацией соответствующего объекта.

  3. Создать один или несколько источников света, расставить их на сцене и включить их.

  4. Если необходимо, включить дополнительные режимы освещения, например, обработку отражаемого света.

Сперва мы объявляем глобальный буфер вершин в котором будут храниться данные вершин пирамиды:

IDirect3DVertexBuffer9* Pyramid = 0;

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

bool Setup()
{
     Device->SetRenderState(D3DRS_LIGHTING, true);

Затем мы создаем буфер вершин, блокируем его и задаем данные вершин, образующих треугольную пирамиду. Нормали вершин вычисляются с помощью описанного в разделе 5.3 алгоритма. Обратите внимание, что хотя треугольники совместно используют некоторые вершины, нормали у каждого из них свои; так что использование для данного объекта списка индексов не принесет никакой пользы. Например, все грани используют вершину (0, 1, 0), находящуюся на верху пирамиды; однако нормаль этой вершины у каждого треугольника указывает в своем направлении.

     Device->CreateVertexBuffer(
               12 * sizeof(Vertex),
               D3DUSAGE_WRITEONLY,
               Vertex::FVF,
               D3DPOOL_MANAGED,
               &Pyramid,
               0);

     // Заполняем буфер вершин данными пирамиды
     Vertex* v;
     Pyramid->Lock(0, 0, (void**)&v, 0);

     // передняя грань
     v[0] = Vertex(-1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f);
     v[1] = Vertex( 0.0f, 1.0f,  0.0f, 0.0f, 0.707f, -0.707f);
     v[2] = Vertex( 1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f);

     // левая грань
     v[3] = Vertex(-1.0f, 0.0f,  1.0f, -0.707f, 0.707f, 0.0f);
     v[4] = Vertex( 0.0f, 1.0f,  0.0f, -0.707f, 0.707f, 0.0f);
     v[5] = Vertex(-1.0f, 0.0f, -1.0f, -0.707f, 0.707f, 0.0f);

     // правая грань
     v[6] = Vertex( 1.0f, 0.0f, -1.0f, 0.707f, 0.707f, 0.0f);
     v[7] = Vertex( 0.0f, 1.0f,  0.0f, 0.707f, 0.707f, 0.0f);
     v[8] = Vertex( 1.0f, 0.0f,  1.0f, 0.707f, 0.707f, 0.0f);

     // задняя грань
     v[9]  = Vertex( 1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f);
     v[10] = Vertex( 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, 0.707f);
     v[11] = Vertex(-1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f);

     Pyramid->Unlock();

После того, как данные вершин для нашего объекта сгенерированы, мы описываем взаимодействие объекта со световыми лучами путем задания материала. В данном примере пирамида отражает белый свет, сама не испускает света и формирует блики.

     D3DMATERIAL9 mtrl;
          mtrl.Ambient  = d3d::WHITE;
          mtrl.Diffuse  = d3d::WHITE;
          mtrl.Specular = d3d::WHITE;
          mtrl.Emissive = d3d::BLACK;
          mtrl.Power    = 5.0f;

     Device->SetMaterial(&mtrl);

Теперь мы создаем и включаем источник направленного света. Лучи направленного света распространяются параллельно оси X в положительном направлении. Рассеиваемая составляющая света окрашена в белый цвет и имеет максимальную интенсивность (dir.Diffuse = WHITE), отражаемая составляющая также белого цвета, но малой интенсивности (dir.Specular = WHITE * 0.3f), а фоновая составляющая — белого цвета и средней интенсивности (dir.Ambient = WHITE * 0.6f).

     D3DLIGHT9 dir;
     ::ZeroMemory(&dir, sizeof(dir));

     dir.Type      = D3DLIGHT_DIRECTIONAL;
     dir.Diffuse   = d3d::WHITE;
     dir.Specular  = d3d::WHITE * 0.3f;
     dir.Ambient   = d3d::WHITE * 0.6f;
     dir.Direction = D3DXVECTOR3(1.0f, 0.0f, 0.0f);

     Device->SetLight(0, &dir);
     Device->LightEnable(0, true);

И, наконец, мы устанавливаем режимы визуализации для ренормализации нормалей и разрешения обработки отражаемой составляющей света.

     Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
     Device->SetRenderState(D3DRS_SPECULARENABLE, true);

     // ... код инициализации матрицы вида и матрицы проекции опущен

     return true;
}

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz