Файлы к лабораторной работе Вы можете скачать здесь.
Вся
Чтобы не создавать приложение с нуля, мы воспользуемся результатами работы №10 и некоторыми предварительными преобразованиями подготовим ее для решения поставленной задачи.
Создайте
новый пустой проект с именем RenderCube типа C#
Вызовите
контекстное меню для имени проекта или узла References в
панели Solution Explorer (или в меню Project оболочки),
чтобы открыть окно добавления ссылок на необходимые для
проекта библиотеки DLL
Добавьте
к проекту, удерживая клавишу Ctrl, ссылки на библиотекиSystem.dllSystem.Drawing.dllSystem.Windows.Forms.dllMicrosoft.DirectX .dllMicrosoft.DirectX .Direct3D .dll
В
панели Solution Explorer выделите узел проекта и с помощью
команды Add
Existing Item меню Project оболочки
добавьте к проекту файлы Form1.cs и Program.cs из лабораторной работы №10Файл Form1.Designer.cs является подчиненным
файлу Form1.cs и скопируется оболочкой
автоматически.

Оболочка скопирует эти файлы в каталог размещения нового проекта.
Убедитесь,
что на данном этапе панель Solution Explorer проекта выглядит
так
Вызовите
окно Find and Replace комбинацией клавиш Ctrl-H (или командой Edit/Find and Replace /Quick Replace ),
настройте его в соответствии с рисунком и щелкните на кнопке Replace All
Оболочка выполнит во всех файлах замену пространства имен SimpleMedia на RenderCube.
Это действие нужно для того, чтобы
Для того, чтобы упростить задачу - не задавать координаты
нормалей, настроим наш код на работу без источника света. Для
этого вместо режима использования структуры PositionNormalColored нужно
применить структуру PositionColored и отключить
источник света.
Откройте
файл Form1.cs в режиме View Code,
вызовите окно Find
and Replace комбинацией
клавиш Ctrl-H и при настройке Currend Document выполните
замену PositionNormalColored на PositionColored
Через
раскрывающийся список Members редактора
кода позиционируйтесь на обработчике vb_Created() и
удалите из него код создания нормалей к вершинам
треугольника// Дополнить вершины параметрами нормалей
verts[0].SetNormal(new Vector3(0.0F, 0.0F, -1.0F));
verts[1].SetNormal(new Vector3(0.0F, 0.0F, -1.0F));
verts[2].SetNormal(new Vector3(0.0F, 0.0F, -1.0F));
Удалите
из функции OnPaint() код настройки источника света// Настроить параметры света источника с номером 0
device.Lights[0].Type = LightType.Point; // Точечный источник
// По умолчанию (0,0,0) - источник в начале координат
device.Lights[0].Position = new Vector3();
// Свет диффузионный белый
device.Lights[0].Diffuse = System.Drawing.Color.White;
// Затухание света при удалении
device.Lights[0].Attenuation0 = 0.2f;
// Дальность освещения, поддерживаемая устройством
device.Lights[0].Range = 1000.0f;
// Принять настройки
device.Lights[0].Commit();
// Установить активным
device.Lights[0].Enabled = true;
В
функции SetupCamera() отключите освещение
сцены, установив флаг device.RenderState.Lighting конвейера
в состояние false
Установите
режим Release работы компилятора и
запустите приложение, чтобы проверить, что на данном
этапе оно функционирует
нормально
Мы видим, что одновременно запускаются два окна: консольное и графическое. Отключим консольное окно.
В
панели Solution Explorer для узла проекта вызовите контекстное
меню и выполните команду Properties
Для
вкладки Application окна свойств проекта
установите свойство Output
type в
значение Windows
Application и закройте это окно свойств
Запустите
приложение в режиме Debug и убедитесь, что консольное окно
больше не появляетсяНа этом подготовительный этап к выполнению данной лабораторной работы завершен.
Смоделируем куб, показанный на рисунке

У нашего куба будет 6 граней. Для представления каждой грани двумя треугольниками потребуется всего 12 треугольников, каждый из которых будет описываться 3 вершинами. Итого, для полного описания куба нужно задать координаты 36 вершин для аппроксимирующих треугольников.
В
панели Solution Explorer вызовите контекстное меню для
файла Form1.cs и выполните команду View Code
В
верхней части рабочей области редактора раскройте правый
список Members и позиционируйтесь на функции vb_Created(),
которую перепишите следующим
образомvoid vb_Created(object sender, EventArgs e)
{
// Определить внутреннюю ссылку на вершинный буфер
VertexBuffer buffer = (VertexBuffer)sender; // Явное приведение типов
// Создать локальный массив структур непреобразованных координат
CustomVertex.PositionColored[] verts = new
CustomVertex.PositionColored[36];
// Задать параметры аппроксимирующих треугольников
// Порядок обхода вершин для лицевой стороны правый
// (по часовой стрелке), для невидимой - левый
//
// Задняя грань: треугольник 2-0-1 (невидимая сторона - обход левый)
verts[0] = new CustomVertex.PositionColored(1.0F, 1.0F, 1.0F, Color.Red.ToArgb());
verts[1] = new CustomVertex.PositionColored(-1.0F, 1.0F, 1.0F, Color.Red.ToArgb());
verts[2] = new CustomVertex.PositionColored(-1.0F, -1.0F, 1.0F, Color.Red.ToArgb());
// Задняя грань: треугольник 2-1-3 (невидимая сторона - обход левый)
verts[3] = new CustomVertex.PositionColored(1.0F, 1.0F, 1.0F, Color.Red.ToArgb());
verts[4] = new CustomVertex.PositionColored(-1.0F, -1.0F, 1.0F, Color.Red.ToArgb());
verts[5] = new CustomVertex.PositionColored(1.0F, -1.0F, 1.0F, Color.Red.ToArgb());
//
// Передняя грань: треугольник 5-6-4 (лицевая сторона - обход правый)
verts[6] = new CustomVertex.PositionColored(1.0F, 1.0F, -1.0F, Color.Blue.ToArgb());
verts[7] = new CustomVertex.PositionColored(-1.0F, -1.0F, -1.0F, Color.Blue.ToArgb());
verts[8] = new CustomVertex.PositionColored(-1.0F, 1.0F, -1.0F, Color.Blue.ToArgb());
// Передняя грань: треугольник 5-7-6 (лицевая сторона - обход правый)
verts[9] = new CustomVertex.PositionColored(1.0F, 1.0F, -1.0F, Color.Blue.ToArgb());
verts[10] = new CustomVertex.PositionColored(1.0F, -1.0F, -1.0F, Color.Blue.ToArgb());
verts[11] = new CustomVertex.PositionColored(-1.0F, -1.0F, -1.0F, Color.Blue.ToArgb());
//
// Верхняя грань: треугольник 0-5-4 (лицевая сторона - обход правый)
verts[12] = new CustomVertex.PositionColored(-1.0F, 1.0F, 1.0F, Color.Yellow.ToArgb());
verts[13] = new CustomVertex.PositionColored(1.0F, 1.0F, -1.0F, Color.Yellow.ToArgb());
verts[14] = new CustomVertex.PositionColored(-1.0F, 1.0F, -1.0F, Color.Yellow.ToArgb());
// Верхняя грань: треугольник 0-2-5 (лицевая сторона - обход правый)
verts[15] = new CustomVertex.PositionColored(-1.0F, 1.0F, 1.0F, Color.Yellow.ToArgb());
verts[16] = new CustomVertex.PositionColored(1.0F, 1.0F, 1.0F, Color.Yellow.ToArgb());
verts[17] = new CustomVertex.PositionColored(1.0F, 1.0F, -1.0F, Color.Yellow.ToArgb());
//
// Нижняя грань: треугольник 1-6-7 (невидимая сторона - обход левый)
verts[18] = new CustomVertex.PositionColored(-1.0F, -1.0F, 1.0F, Color.Black.ToArgb());
verts[19] = new CustomVertex.PositionColored(-1.0F, -1.0F, -1.0F, Color.Black.ToArgb());
verts[20] = new CustomVertex.PositionColored(1.0F, -1.0F, -1.0F, Color.Black.ToArgb());
// Нижняя грань: треугольник 1-7-3 (невидимая сторона - обход левый)
verts[21] = new CustomVertex.PositionColored(-1.0F, -1.0F, 1.0F, Color.Black.ToArgb());
verts[22] = new CustomVertex.PositionColored(1.0F, -1.0F, -1.0F, Color.Black.ToArgb());
verts[23] = new CustomVertex.PositionColored(1.0F, -1.0F, 1.0F, Color.Black.ToArgb());
//
// Левая грань: треугольник 0-6-1 (невидимая сторона - обход левый)
verts[24] = new CustomVertex.PositionColored(-1.0F, 1.0F, 1.0F, Color.Gray.ToArgb());
verts[25] = new CustomVertex.PositionColored(-1.0F, -1.0F, -1.0F, Color.Gray.ToArgb());
verts[26] = new CustomVertex.PositionColored(-1.0F, -1.0F, 1.0F, Color.Gray.ToArgb());
// Левая грань: треугольник 0-4-6 (невидимая сторона - обход левый)
verts[27] = new CustomVertex.PositionColored(-1.0F, 1.0F, 1.0F, Color.Gray.ToArgb());
verts[28] = new CustomVertex.PositionColored(-1.0F, 1.0F, -1.0F, Color.Gray.ToArgb());
verts[29] = new CustomVertex.PositionColored(-1.0F, -1.0F, -1.0F, Color.Gray.ToArgb());
//
// Правая грань: треугольник 2-3-7 (лицевая сторона - обход правый)
verts[30] = new CustomVertex.PositionColored(1.0F, 1.0F, 1.0F, Color.Green.ToArgb());
verts[31] = new CustomVertex.PositionColored(1.0F, -1.0F, 1.0F, Color.Green.ToArgb());
verts[32] = new CustomVertex.PositionColored(1.0F, -1.0F, -1.0F, Color.Green.ToArgb());
// Правая грань: треугольник 2-7-5 (лицевая сторона - обход правый)
verts[33] = new CustomVertex.PositionColored(1.0F, 1.0F, 1.0F, Color.Green.ToArgb());
verts[34] = new CustomVertex.PositionColored(1.0F, -1.0F, -1.0F, Color.Green.ToArgb());
verts[35] = new CustomVertex.PositionColored(1.0F, 1.0F, -1.0F, Color.Green.ToArgb());
// Заполнить вершинный буфер данными треугольников
buffer.SetData(verts, 0, LockFlags.None);
}
Координаты вершин треугольников заданы в соответствии с
рисунком. Теперь нужно привести в соответствие новой задачи
и остальной
Через
раскрывающийся список Members найдите в функции InitializeGraphics() код
создания вершинного буфера и измените количество вершин
аппроксимирующих треугольников с 3 на 36// Создать вершинный буфер
vb = new VertexBuffer(typeof(CustomVertex.PositionColored),
36,
device,
Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionColored.Format,
Pool.Default);
Мы моделируем объемную фигуру и нам не нужно делать видимой
обратную сторону каждой плоской грани, как это было с треугольником,
поэтому отключим эту возможность .
Найдите
функцию SetupCamera() и закомментируйте
в ней следующий код// Не скрывать обратную сторону плоской фигуры
// device.RenderState.CullMode = Cull.None;
Изменим характер вращения куба, чтобы получить более эффективную картинку.
Найдите
в конце функции SetupCamera() секцию кода
преобразования координат объекта и замените его на следующую// Преобразование пространства для произвольных поворотов
/*
device.Transform.World = Matrix.RotationAxis(
new Vector3(angle / ((float)Math.PI * 2.0F),
angle / ((float)Math.PI * 4.0F),
angle / ((float)Math.PI * 6.0F)),
angle / (float)Math.PI);
*/
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
angle += 0.1F;
Здесь мы применили для поворота куба RotationYawPitchRoll() структуры Microsoft.
RotationYawPitchRoll(float yaw, float pitch, float roll)
где -отклонение, -шаг, roll -поворот.
Мы рисуем в данном приложении 12 примитивов-треугольников,
поэтому нужно установить это количество в функции рисования DrawPrimitives() устройства.
Найдите
в методе OnPaint() секцию кода " Сформировать
сцену..." и установите в ней нужную размерность
примитивов рисования// Сформировать сцену с учетом параметров
// "положение-нормаль-цвет"
device.BeginScene();
// Установить формат обработки вершин при отображении
device.VertexFormat = CustomVertex.PositionColored.Format;
// Нарисовать треугольник по данным из буфера
device.SetStreamSource(0, vb, 0);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
device.EndScene();
Постройте
приложение и убедитесь, что рисуется вращающийся куб с
цветными гранями
Добавим к приложению возможность останавливать и возобнавлять вращение куба, чтобы можно было полюбоваться на созданную красоту.
В
конструкторе формы Form1() подпишитесь
на событие Click самой формы, начиная
вводить код this.Click+=,
а дальше нажимайте клавишу Tab до создания
заготовки обработчика Form1_Click()
Объявите
и сразу инициализируйте в классе Form1 локальное
булево поле flagRotate,
а также заполните обработчикbool flagRotate = true;
void Form1_Click(object sender, EventArgs e)
{
flagRotate = !flagRotate;
}
В
функции SetupCamera() посадите angle на условие проверки состояния флагаif (flagRotate)
angle += 0.1F;
Запустите
приложение и убедитесь, что щелчки на клиентской области
формы управляют вращением кубаСоздадим сцену с тремя вращающимися кубами.
Откройте
через панель Solution Explorer файл Program.cs, скопируйте
из него код точки входа приложения Main() и
разместите его в классе Form1 перед конструктором
классаpublic partial class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (Form1 frm = new Form1())
{
// Показать форму перед созданием движка
frm.Show();
// Создать и инициализировать графический движок
// нашей функцией
frm.InitializeGraphics();
// Войти в цикл сообщений
Application.Run(frm);
}
}
public Form1()
{
InitializeComponent();
.....
}
.....
}
Удалите
совсем файл Program.cs
Откройте
панель Solution Explorer и щелкните правой
кнопкой мыши на файле Form1.cs. Выполните
команду Copy, затем щелкните
правой кнопкой мыши на узле проекта RenderCube и
выполните команду Paste контекстного
меню.
Измените
имя полученной копии на Form2.cs
Откройте
файл Form2.cs в режиме View
Code и
замените все вхождения Form1 на Form2,
вызвав окно замены комбинацией клавиш Ctrl-H и
настроив его опцию Look in в значение Current Document
Откройте
файл Form2.designer.cs и выполните в нем предыдущую замену
всех вхождений Form1 на Form2
В
меню Project оболочки выполните последнюю
команду RenderCube Properties, чтобы вызвать
окно свойств проекта. Установите свойство Startup
object в значение
начального старта второй формы
Запустите
приложение, чтобы убедиться, что в скопированной форме Form2 предыдущий
код работает
Теперь мы можем приступить к усложнению кода, который будет
реализован в форме Form2 приложения. Долее
мы хотим отобразить три вращающихся раскрашенных куба. Было
бы неэффективно создавать три вершинных буфера (один буфер
для каждого объекта). Можно использовать один и тот же вершинный
буфер многократно, взяв за основу первый куб, а для двух
других кубов перед рисованием сдвигать координаты первого
куба в мировой
В
конце функции SetupCamera() найдите секцию кода// Преобразование пространства для произвольных поворотов
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
Перенесите
этот код в функцию OnPaint() в место, которое находится
перед функциейdevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
Добавьте
после этой функции следующий код для рисования еще двух
кубов, чтобы общий код секции "Сформировать сцену"
выглядел такprotected override void OnPaint(PaintEventArgs e)
{
// Очистить цветом клиентскую область формы
device.Clear(ClearFlags.Target,
System.Drawing.Color.CornflowerBlue,
1.0F, 0);
// Вызов нашей функции установки камеры
SetupCamera();
// Сформировать сцену с учетом параметров
// "положение-нормаль-цвет"
device.BeginScene();
// Установить формат обработки вершин при отображении
device.VertexFormat = CustomVertex.PositionColored.Format;
// Заполнить устройство данными из буфера
device.SetStreamSource(0, vb, 0);
// Преобразование пространства для произвольных поворотов
// Первый куб
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
// Второй куб
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI / 2.0F,
angle / (float)Math.PI * 4.0F) *
Matrix.Translation(-4.0F, 0.0F, 0.0F);// Сдвиг влево
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
// Третий куб
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 4.0F,
angle / (float)Math.PI / 2.0F) *
Matrix.Translation(4.0F, 0.0F, 0.0F);// Сдвиг вправо
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
device.EndScene();
// Показать буфер кадра
device.Present();
// Принудительно перерисовать
this.Invalidate();
}
В коде перед рисованием очередного куба мы осуществляем
преобразование вершин объекта в устройстве, применяя последовательно
матрицу вращения и
матрицу перемещения .
Второй куб мы сдвигаем на 4 единицы влево относительно первого,
третий - на 4 единицы вправо.
Запустите
приложение и увеличьте размер окна по ширине, должна получиться
следующая картина
Поскольку наши текущие параметры камеры настроены на первый куб, то для охвата всей сцены нужно переместить камеру немного назад. Заодно уменьшим скорость вращения кубов.
Внесите
в код функции 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 = false;
if (flagRotate)
angle += 0.02F;
}
Постройте
приложение, должен получиться примерно такой результат
Нанесем на стороны куба какие-нибудь рисунки. Это могут
быть любые плоские -рисунки. Для текстурирования объектов
в используется понятие тексела (
Для того, чтобы отобразить кубический объект с использованием
текстурирования, нужно изменить вершинный формат объекта,
а также данные, пересылаемые в
В
панели Solution Explorer проекта получите
через контекстное меню копию файла Form1.cs и
переименуйте эту копию в файл Form3.cs
Вызовите
комбинацией клавиш Ctrl-H окно замены
текстового редактора для файла Form3.cs и
замените все вхождения Form1 на Form3
Откройте
файл Form3.designer.cs и выполните в нем те же самые замены
Через
меню Project откройте окно свойств проекта
и установите на вкладке Application в качестве стартового
объект класса Form3
Запустите
приложение, чтобы убедиться, что версия класса Form3 работоспособна
и равнозначна по функциональности Form1На этом подготовительная часть задачи текстурирования сторон куба завершена и можно приступать к основной части.
Измените
тело обработчика vb_Created() так, как показано нижеprivate void vb_Created(object sender, EventArgs e)
{
// Определить внутреннюю ссылку на вершинный буфер
VertexBuffer buffer = (VertexBuffer) sender; // Явное приведение типов
// Создать локальный массив структур непреобразованных координат
CustomVertex.PositionTextured[] verts = new
CustomVertex.PositionTextured[36];
// Задать параметры аппроксимирующих треугольников
verts[0] = new CustomVertex.PositionTextured(-1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[1] = new CustomVertex.PositionTextured(-1.0F, -1.0F, 1.0F, 0.0F, 1.0F);
verts[2] = new CustomVertex.PositionTextured(1.0F, 1.0F, 1.0F, 1.0F, 0.0F);
verts[3] = new CustomVertex.PositionTextured(-1.0F, -1.0F, 1.0F, 0.0F, 1.0F);
verts[4] = new CustomVertex.PositionTextured(1.0F, -1.0F, 1.0F, 1.0F, 1.0F);
verts[5] = new CustomVertex.PositionTextured(1.0F, 1.0F, 1.0F, 1.0F, 0.0F);
verts[6] = new CustomVertex.PositionTextured(-1.0F, 1.0F, -1.0F, 0.0F, 0.0F);
verts[7] = new CustomVertex.PositionTextured(1.0F, 1.0F, -1.0F, 1.0F, 0.0F);
verts[8] = new CustomVertex.PositionTextured(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F);
verts[9] = new CustomVertex.PositionTextured(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F);
verts[10] = new CustomVertex.PositionTextured(1.0F, 1.0F, -1.0F, 1.0F, 0.0F);
verts[11] = new CustomVertex.PositionTextured(1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
verts[12] = new CustomVertex.PositionTextured(-1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[13] = new CustomVertex.PositionTextured(1.0F, 1.0F, -1.0F, 1.0F, 1.0F);
verts[14] = new CustomVertex.PositionTextured(-1.0F, 1.0F, -1.0F, 0.0F, 1.0F);
verts[15] = new CustomVertex.PositionTextured(-1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[16] = new CustomVertex.PositionTextured(1.0F, 1.0F, 1.0F, 1.0F, 0.0F);
verts[17] = new CustomVertex.PositionTextured(1.0F, 1.0F, -1.0F, 1.0F, 1.0F);
verts[18] = new CustomVertex.PositionTextured(-1.0F, -1.0F, 1.0F, 0.0F, 0.0F);
verts[19] = new CustomVertex.PositionTextured(-1.0F, -1.0F, -1.0F, 0.0F, 1.0F);
verts[20] = new CustomVertex.PositionTextured(1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
verts[21] = new CustomVertex.PositionTextured(-1.0F, -1.0F, 1.0F, 0.0F, 0.0F);
verts[22] = new CustomVertex.PositionTextured(1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
verts[23] = new CustomVertex.PositionTextured(1.0F, -1.0F, 1.0F, 1.0F, 0.0F);
verts[24] = new CustomVertex.PositionTextured(-1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[25] = new CustomVertex.PositionTextured(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
verts[26] = new CustomVertex.PositionTextured(-1.0F, -1.0F, 1.0F, 1.0F, 0.0F);
verts[27] = new CustomVertex.PositionTextured(-1.0F, 1.0F, -1.0F, 0.0F, 1.0F);
verts[28] = new CustomVertex.PositionTextured(-1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
verts[29] = new CustomVertex.PositionTextured(-1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[30] = new CustomVertex.PositionTextured(1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[31] = new CustomVertex.PositionTextured(1.0F, -1.0F, 1.0F, 1.0F, 0.0F);
verts[32] = new CustomVertex.PositionTextured(1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
verts[33] = new CustomVertex.PositionTextured(1.0F, 1.0F, -1.0F, 0.0F, 1.0F);
verts[34] = new CustomVertex.PositionTextured(1.0F, 1.0F, 1.0F, 0.0F, 0.0F);
verts[35] = new CustomVertex.PositionTextured(1.0F, -1.0F, -1.0F, 1.0F, 1.0F);
// Заполнить вершинный буфер данными треугольников
buffer.SetData(verts, 0, LockFlags.None);
}
При отображении каждая сторона куба будет включать
В
функции InitializeGraphics() измените код создания вершинного
буфера// Создать вершинный буфер
vb = new VertexBuffer(typeof(CustomVertex.PositionTextured),
36,
device,
Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionTextured.Format,
Pool.Default);
В
функции 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, 5.0F), // Положение камеры
new Vector3(), // Положение объекта текущее
new Vector3(0, 1, 0)); // Направление камеры
// Освещение
device.RenderState.Lighting = false;
// Не скрывать обратную сторону плоской фигуры
// device.RenderState.CullMode = Cull.None;
// Преобразование пространства для произвольных поворотов
/*
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
*/
if (flagRotate)
angle += 0.02F;
}
Перенесите
вырезанный код в функцию OnPaint() и
вставьте перед вызовом функции рисования DrawPrimitives().
Откорректируйте определения формата устройстваprotected override void OnPaint(PaintEventArgs e)
{
// Очистить цветом клиентскую область формы
device.Clear(ClearFlags.Target,
System.Drawing.Color.CornflowerBlue,
1.0F, 0);
// Вызов нашей функции установки камеры
SetupCamera();
// Сформировать сцену с учетом параметров
// "положение-нормаль-цвет"
device.BeginScene();
// Установить формат обработки вершин при отображении
device.VertexFormat = CustomVertex.PositionTextured.Format;
// Нарисовать треугольник по данным из буфера
device.SetStreamSource(0, vb, 0);
// Преобразование пространства для произвольных поворотов
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
device.EndScene();
// Показать буфер кадра
device.Present();
// Принудительно перерисовать
this.Invalidate();
}
Вставьте
в секцию "Сформировать сцену" опять перед функцией рисования
объекта код установки // Сформировать сцену с учетом параметров
// "положение-нормаль-цвет"
device.BeginScene();
// Установить формат обработки вершин при отображении
device.VertexFormat = CustomVertex.PositionTextured.Format;
// Нарисовать треугольник по данным из буфера
device.SetStreamSource(0, vb, 0);
// Преобразование пространства для произвольных поворотов
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
// Установка текстуры
device.SetTexture(0, texture);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
device.EndScene();
позволяет устанавливать до восьми
типов текстур одновременно для примитива рисования. В данном
коде мы устанавливаем первым параметром только одну .
Класс имеет четыре версии конструктора
lp, Microsoft.device, Microsoft.pool )device,
int width, int height, int numLevels, Microsoft.usage , Microsoft.format, Microsoft.pool )device,
System.Drawing.image, Microsoft.usage , Microsoft.pool )device,
System.IO.data, Microsoft.usage , Microsoft.pool )Мы воспользуемся для создания
Bitmap ,
загружающий рисунок из внедренного ресурса
Добавьте
в секцию определения ссылок-членов класса перед функцией InitializeGraphics() код создания ссылки на private Device device = null;
private VertexBuffer vb = null;
private Texture texture = null;
public void InitializeGraphics()
{
....................................
}
Поместите
в обработчик vb_Created() в самый его
конец после заполнения вершинного буфера данными аппроксимирующих
треугольников код создания управляемого private void vb_Created(object sender, EventArgs e)
{
..........................................
// Заполнить вершинный буфер данными треугольников
buffer.SetData(verts, 0, LockFlags.None);
// Создать объект текстуры
Bitmap bmp = new Bitmap(this.GetType(), "12_16.bmp");
texture = new Texture(device, bmp, 0, Pool.Managed);
}
Здесь в качестве "12_16. из
каталога Source данной лабораторной
работы (вы можете создать свой рисунок в формате ).
В
меню Project выполните команду Add
Existing Item,
установите фильтр открывшегося диалогового окна на Image
Files и
добавьте в проект файл 12_16.bmp
Перейдите
в панель Solution Explorer, выделите файл 12_16.bmp и
через панель Properties установите свойство Build Action = Embedded
Resource (внедренный
ресурс), чтобы компилятор размещал рисунок прямо в файле
исполнимой сборки
Постройте
проект и получите примерно такой результат вращающегося
текстурированного куба
Для
демонстрации вариантов работы преподавателю создайте меню
выбора варианта, как это сделано в Lab45 - WinFormsApp
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.