Опубликован: 13.07.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 14:

Использование Mesh-объектов в DirectX

Добавление материалов и освещения

Для того, чтобы Direct3D правильно вычислял цвет в отдельных точках на трехмерном объекте, кроме цвета источника света нужно еще указать, как объект будет отражать свет определенного цвета. Нам необходимо описать, как поверхность кубов будет отражать свет от источника. Эту особенность задают с помощью материалов. Материалы определяют, каким образом объект будет отражать общий диффузионный свет, какие участки будут освещены больше или меньше, и отражает ли объект свет вообще.

  • Добавьте в начало функции DrawCubes() секцию кода создания материала
private void DrawCubes()
        {
            // Создаем материал поверхности отражения
            // и добавляем его в устройство 
            Material boxMaterial = new Material();
            boxMaterial.Ambient = Color.White;
            boxMaterial.Diffuse = Color.White;
            device.Material = boxMaterial;
    
            //
            // .................................................
            //
    
            if (flagRotate)
                angle += 0.02F;
        }
Листинг 14.13. Добавление материала поверхности отражения света

Здесь мы создаем новый материал и настраиваем в нем значения общего и диффузионного освещения, выбрав белый цвет. Использование белого означает, что мы отразим весь общий и диффузный свет, падающий на объекты. Затем мы передаем этот материал в устройство для рендеринга.

  • Запустите приложение и появятся красные кубы


Если изменить цвет источника общего света, то изменится и цвет кубов. А если изменить цвет материала на отличный от белого, то отражаемый свет будет смесью цвета материала и цвета источника.

Использование более реалистичного освещения

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

  • Добавьте в конец функции SetupCamera() следующую секцию кода
// Установка камеры в сцену
        private void SetupCamera()
        {
            //Создание перспективы 
            device.Transform.Projection = Matrix.PerspectiveFovLH(
                (float)Math.PI / 4, // Угол зрения равен 45 градусов
                                    // Форматное соотношение сторон
                (float)this.ClientSize.Width / (float)this.ClientSize.Height, 
                1.0F,               // Ближний план
                100.0F);            // Дальний план
    
            //Добавление камеры 
            device.Transform.View = Matrix.LookAtLH(
                new Vector3(0, 0, 15.0F),    // Положение камеры
                new Vector3(),              // Положение объекта текущее
                new Vector3(0, 1, 0));      // Направление камеры
    
            // Освещение
            device.RenderState.Lighting = true;
    
            // Установить красный свет
            device.RenderState.Ambient = Color.Red;
    
            // Настроить общий свет
            device.Lights[0].Type = LightType.Directional;
            device.Lights[0].Diffuse = Color.White;
            device.Lights[0].Direction = new Vector3(0, -1, -1);
            device.Lights[0].Commit();
            device.Lights[0].Enabled = true;
        }
Листинг 14.14. Настроить общий свет

Мы создали источник направленного белого света и задали направление освещения.

  • Запустите приложение и убедитесь, что направленые к наблюдателю грани кубов освещены полностью, а повернутые грани кажутся более затененными


Попробуйте создать с теми же настройками света изображение заварочного чайника. Для этого:

  • Замените в функции InitializeGraphics() создание куба на код создания заварочного чайника
public void InitializeGraphics()
        {
            // .................................................
            //mesh = Mesh.Box(device, 2.0F, 2.0F, 2.0F);
            mesh = Mesh.Teapot(device);
        }
Листинг 14.15. Создание изображений заварочных чайников
  • Постройте приложение и получите следующую картинку


Некоторые части объекта проступают на передний план из-за того, что ранее мы удалили буфер глубины.

  • Добавьте в функцию InitializeGraphics() буфер глубины, а в функцию OnPaint() флаг существования буфера глубины, как мы это делали в Form3 лабораторной работы №13 или будем делать в конце этой лабораторной работы №14
  • Запустите приложение с заварочными чайниками и убедитесь, что буфер глубины работает
  • Уберите код буфера глубины и код заварочного чайника и вновь включите код генерации кубов
Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000