Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
◄ Previous activity
Next activity ►
Лабораторна робота11. Досконаліші технології рендеринга в DіrectХ
Для апроксимації тривимірних об'єктів в Direct3D є наступні примітиви:
При малюванні можна використовувати одні і ті ж дані про вершини для будь-якого з цих типів примітивів. Додаток інтерпретуватиме при кожному малюванні той тип примітиву, що йому повідомлюється.
Завдання 1. Відредагувати проект RenderCube з лабораторної роботи 10
Завдання 2. Рендерінг різних типів примітивів
private float angle = 0;// Закритий член класу
// Установка камери в сцену
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.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F
angle / (float)Math.PI);
if (flagRotate)
angle += 0.1F;
}
public Form1()
{
InitializeComponent();
// Усуваємо мерехтіння вікна при нескінченному перемальовуванні
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.Opaque, true);
this.Click += new EventHandler(Form1_Click);
}
bool flagRotate = true;
void Form1_Click(object sender, EventArgs e)
{
flagRotate = !flagRotate;
}
private Device device = null; // Графічний конвеєр
private VertexBuffer vb = null; // Вершинний буфер
private const int NumberItems = 12; // Кількість вершин об'єкту
Кількість вершин 12 тому, що це число парне, ділиться на 3 (що підходить для примітивів LineList і TriangleList) і не настільки велике, щоб захаращувати малюнок. Оголошення змінної як константи доручає компілятору стежити за тим, щоб випадково де-небудь в коді її не змінити.
public void InitializeGraphics()
{
..................................
// Створити вершинний буфер
vb = new VertexBuffer(typeof(CustomVertex.PositionColored),
NumberItems,
device,
Usage.Dynamic | Usage.WriteOnly,
CustomVertex.PositionColored.Format,
Pool.Default)
..................................
}
Змінимо алгоритм завдання координат вершин і заповнення вершинного буфера у функції vb_Created(). Застосуємо засоби випадкового формування координат вершин і їх кольорів.
public Form1()
{
InitializeComponent();
// Усуваємо мерехтіння вікна при нескінченному перемальовуванні
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.Opaque, true);
// Ініціалізація генератора випадкових чисел
rand = new System.Random();
}
private Device device = null; // Графічний конвеєр
private VertexBuffer vb = null; // Вершинний буфер
private const int NumberItems = 12; // Кількість вершин об'єкту
System.Random rand; // Поле для генератора випадкових чисел
void vb_Created(object sender, EventArgs e)
{
// Визначити внутрішнє посилання на вершинний буфер
VertexBuffer buffer = (VertexBuffer)sender; // Явне приведення типів
// Створити локальний масив посилань для вершин об'єкту
CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[NumberItems];
// Згенерувати випадково координати і кольори вершин
double factor = 2.5d;// Ваговий коефіцієнт
for (int i = 0; i < NumberItems; i++)
{
float xPos = (float)((rand.NextDouble() - rand.NextDouble()) * factor);
float yPos = (float)((rand.NextDouble() - rand.NextDouble()) * factor);
float zPos = (float)((rand.NextDouble() - rand.NextDouble()) * factor);
verts[i].Position = new Vector3(xPos, yPos, zPos);
verts[i].Color = System.Drawing.Color.FromArgb(rand.Next(256),
rand.Next(256),
rand.Next(256)).ToArgb();
}
// Заповнити вершинний буфер даними трикутників
buffer.SetData(verts, 0, LockFlags.None);
}
Організувати проглядання роботи різних примітивів можна послідовним їх перебором з достатньою затримкою. Саму затримку можна вимірювати як різницю в тимчасових тактах процесора між поточним часом і часом запуску додатку і на цей час відображати об'єкт одним і тим же примітивом. Після завершення чергового циклу перебору всіх примітивів необхідно згенерувати нові параметри вершинного буфера, щоб випадково змінити мальований об'єкт.
// Прапорецьгенерації вершин перед початком
// кожного нового циклу обходу всіх примітивів.
// Перше заповнення вершинного буфера виконане
// у InitializeGraphics() при запуску додатку
private bool needRecreate = false;
// Захоплення стартового часу в тактах
private static readonly int beginTickCount =
System.Environment.TickCount;
protected override void OnPaint(PaintEventArgs e)
{
........................................
}
Змінна beginTickCount оголошена як статична для того, щоб її дані зберігалися в об'єкті-типі, а не об'єкті-екземплярі, на випадок, якщо буде створено декілька екземплярів класу Form1. Ключове слово readonly робить її доступною "тільки для читання". На відміну від константних змінних, що вимагають негайної ініціалізації при оголошенні, змінні "тільки для читання" допускають відкладену ініціалізацію в конструкторі класу.
// Прапорецьгенерації вершин перед початком
// кожного нового циклу обходу всіх примітивів.
// Перше заповнення вершинного буфера виконане
// у InitializeGraphics() при запуску додатку
private bool needRecreate = false;
// Захоплення стартового часу в тактах
private static readonly int beginTickCount =
System.Environment.TickCount;
protected override void OnPaint(PaintEventArgs e)
{
// Очистити кольором клієнтську область форми
device.Clear(ClearFlags.Target,
System.Drawing.Color.White,
1.0F, 0);
// Виклик функції установки камери
SetupCamera();
// Сформувати сцену з урахуванням параметрів
// "положення-нормаль-колір"
device.BeginScene();
// Встановити формат обробки вершин при відображенні
device.VertexFormat = CustomVertex.PositionColored.Format;
// Намалювати трикутник даним з буфера
device.SetStreamSource(0, vb, 0);
const int countTime = 5 * 1000; // Тримати зображення 5 секунд
const int countIndex = 6; // Кількість варіантів показу
int index = ((System.Environment.TickCount - beginTickCount) / countTime)
% countIndex;
switch (index)
{
case 0: // PointList
device.DrawPrimitives(PrimitiveType.PointList, 0, NumberItems);
if (needRecreate) // Виконати тільки при черговому index == 0
{
vb_Created(vb, null);// Згенерувати новий вершинний буфер
needRecreate = false;// Скинути прапор регенерації вершин
}
this.Text = "Несполучені точки вершин";
break;
case 1: // LineList
device.DrawPrimitives(PrimitiveType.LineList, 0, NumberItems / 2);
needRecreate = true;// Приготувати прапорець для генерації вершин
// при index == 0
this.Text = "З'єднання пар вершин лініями";
break;
case 2: // LineStrip
device.DrawPrimitives(PrimitiveType.LineStrip, 0, NumberItems - 1);
this.Text = "З'єднання вершин ламаною";
break;
case 3: // TriangleList
device.DrawPrimitives(PrimitiveType.TriangleList, 0, NumberItems / 3);
this.Text = "Окремі трикутники";
break;
case 4: // TriangleStrip
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, NumberItems - 2);
this.Text = "Безперервна ферма трикутників";
break;
case 5: // TriangleFan
device.DrawPrimitives(PrimitiveType.TriangleFan, 0, NumberItems - 2);
this.Text = "Трикутне віяло з точки";
break;
}
device.EndScene();
// Показати буфер кадру
device.Present();
// Примусово перемальовувати
this.Invalidate();
}
// Установка камери в сцену
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.PointSize = 5.0f;
}
Завдання 4. Використання індексних буферів
Ще раз розглянемо геометрію куба з попередніх робіт.
Ми апроксимували кожну сторону куба двома трикутниками, задаючи координати вершин кожного трикутника. Ці трикутника у вершинах куба мали однакові координати і багато разів повторювалися при описі трикутників. Код був надмірним і достатньо великим.
Для усунення надмірності зручніше у вершинному буфері задавати тільки координати унікальних точок, якими є вершини куба, а для кожного апроксимуючого трикутника указувати три індекси з масиву вершинного буфера. Ми зберігаємо унікальні координати об'єкту "внавал" окремо, а для трикутних примітивів указуємо триадний список індексів цих координат в масиві вершинного буфера. Такий підхід істотно скорочує кількість даних, що зберігаються, і зменшує необхідну пам'ять комп'ютера.
Масив з індексами опорних точок об'єкту, записаних у вершинному буфері, називається індексним буфером. Індекси, що зберігаються в такому буфері, можуть бути 16- або 32-розрядними цілими числами. Давайте використаємо індексний буфер для моделювання трикутника, що обертається.
Тепер потрібно встановити форму Form2 стартовою для можливості її початкового запуску. Для цього:
void vb_Created(object sender, EventArgs e)
{
// Визначити внутрішнє посилання на вершинний буфер
VertexBuffer buffer = (VertexBuffer)sender; // Явне приведення типів
// Створити локальний масив структур неперетворених координат
CustomVertex.PositionColored[] verts =
new CustomVertex.PositionColored[8]; // Задати розмірність масиву на 8 вершин
// Задати параметри вершин куба відповідно до малюнка
//
verts[0]= new CustomVertex.PositionColored(-1.0F, 1.0F, 1.0F, Color.Purple.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.Blue.ToArgb());
verts[3]= new CustomVertex.PositionColored(1.0F, -1.0F, 1.0F, Color.Yellow.ToArgb());
verts[4]= new CustomVertex.PositionColored(-1.0F, 1.0F, -1.0F, Color.Gold.ToArgb());
verts[5]= new CustomVertex.PositionColored(1.0F, 1.0F, -1.0F, Color.Green.ToArgb());
verts[6]= new CustomVertex.PositionColored(-1.0F, -1.0F, -1.0F, Color.Black.ToArgb());
verts[7]= new CustomVertex.PositionColored(1.0F, -1.0F, -1.0F, Color.WhiteSmoke.ToArgb());
// Заповнити вершинний буфер даними трикутників
buffer.SetData(verts, 0, LockFlags.None);
}
Ми істотно зменшили код створення вершинного буфера, залишивши тільки координати, необхідні для визначення вершин куба. До того ж, для кожної вершини куба ми задали окремий колір.
// Створити вершинний буфер
vb = new VertexBuffer(typeof(CustomVertex.PositionColored),8,device,Usage.Dynamic | Usage.WriteOnly,CustomVertex.PositionColored.Format,
Pool.Default);
// Визначення індексного масиву вершин трикутних примітивів
private static readonly short[] indices = {
2,0,1,// Задня грань: трикутник 2-0-1 (невидима сторона - обхід лівий)
2,1,3,// Задня грань: трикутник 2-1-3 (невидима сторона - обхід лівий)
5,6,4,// Передня грань: трикутник 5-6-4 (лицьова сторона - обхід правий)
5,7,6,// Передня грань: трикутник 5-7-6 (лицьова сторона - обхід правий)
0,5,4,// Верхня грань: трикутник 0-5-4 (лицьова сторона - обхід правий)
0,2,5,// Верхня грань: трикутник 0-2-5 (лицьова сторона - обхід правий)
1,6,7,// Нижня грань: трикутник 1-6-7 (невидима сторона - обхід лівий)
1,7,3,// Нижня грань: трикутник 1-7-3 (невидима сторона - обхід лівий)
0,6,1,// Ліва грань: трикутник 0-6-1 (невидима сторона - обхід лівий)
0,4,6,// Ліва грань: трикутник 0-4-6 (невидима сторона - обхід лівий)
2,3,7,// Права грань: трикутник 2-3-7 (лицьова сторона - обхід правий)
2,7,5 // Права грань: трикутник 2-7-5 (лицьова сторона - обхід правий)
};
private Device device = null;
private VertexBuffer vb = null;
private IndexBuffer ib = null;
public void InitializeGraphics()
{
.....................
}
Тепер необхідно створити сам індексний буфер, куди можна буде передати для зберігання і використання індекси координат вершинного буфера. Індексний буфер має властивість скидатися також, як вершинний, тому необхідно передбачити обробник відновлення індексного буфера для події Created, а також примусовий виклик цього обробник при першому запуску форми.
public void InitializeGraphics()
{
// Створення об'єкту і настройка параметрів представлення
// Створити об'єкт параметрів представлення
PresentParameters presentParams = new PresentParameters();
// Встановити віконний режим
presentParams.Windowed = true;
// Скидати вміст буфера, якщо він не готовий до представлення
presentParams.SwapEffect = SwapEffect.Discard;
// Створити об'єкт пристрою і зберегти посилання на нього
device = new Device(0, DeviceType.Hardware, this,CreateFlags.SoftwareVertexProcessing, presentParams);
// Перехоплення події зміни форми для скидання пристрою
// Створити вершинний буфер
vb = new VertexBuffer(typeof(CustomVertex.PositionColored), 8, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format,
Pool.Default);
// Реєстрація події Created вершинного буфера
vb.Created += new EventHandler(vb_Created);
// Створити індексний буфер для координат вершин куба
ib = new IndexBuffer(typeof(short),indices.Length,device,
Usage.WriteOnly,
Pool.Default);
// Реєстрація події Created індексного буфера
// Код написати уручну (для створення обробника)!!!
ib.Created += new EventHandler(ib_Created);
// Примусовий виклик обробника при першому запуску
ib_Created(ib, null);
}
// Обробник події повторного заповнення індексного буфера
void ib_Created(object sender, EventArgs e)
{
IndexBuffer buffer = (IndexBuffer)sender;
buffer.SetData(indices, 0, LockFlags.None);
}
Тепер необхідно зареєструвати індексний буфер в пристрої device, щоб функція малювання об'єкту використовувала його.
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F,
angle / (float)Math.PI);
if (flagRotate)
angle += 0.02F;
// Сформувати сцену з урахуванням параметрів
// "положення-нормаль-колір"
device.BeginScene();
// Встановити формат обробки вершин при відображенні
device.VertexFormat = CustomVertex.PositionColored.Format;
// Намалювати трикутник даним з буфера
device.SetStreamSource(0, vb, 0);
device.Indices = ib;
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
device.EndScene();
Функція малювання, яку ми використовували, має наступний синтаксис
public void DrawIndexedPrimitives(
Microsoft.DirectX.Direct3D.PrimitiveType primitiveType, // Чим малюємо
System.Int32 baseVertex, // Зсув від початок буфера до індексу першої вершини
System.Int32 minVertexIndex, // Мінімальний індекс вершини в поточному виклику
System.Int32 numVertices, // Число вершин, використовуваних в поточному виклику
System.Int32 startIndex, // Стартовий індекс для прочитування і відображення
System.Int32 primCount) // Число примітивів, що відображаються
Тут ми не зможемо зробити кожну окрему грань одноколірною, оскільки колір примітиву береться з параметрів вершини, а у нас задані кольори вершин куба, до яких примикають відразу декілька примітивів різних граней.
Завдання 5. Створення декількох кубів, що обертаються, із застосуванням буфера глибини
Буфер глибини (depth buffer, Z-буфер, W-буфер) застосовується в додатках Direct3D для зберігання інформації про глибину об'єкту, що відображається. Ця інформація використовується в процесі растеризування (з векторної в растрову) для визначення того, наскільки піксели перекривають один одного. На даному етапі наше застосування не має буфера глибини, але в цьому розділі ми його введемо і використаємо.
Запустити проект на виконання і переконаєтись, що Form3 працює в колишньому варіанті Form2, тобто цілісність коду збереглася
Спочатку замість одного куба створимо 9 кубів і для правильного їх відображення відсунемо камеру.
private void DrawCubes()
{
//
// Середній ряд
//
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f) *
Matrix.Translation(0.0f, 0.0f, 0.0f); // По центру
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
//
// Нижній ряд
//
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f) *
Matrix.Translation(0.0f, -4.0f, 0.0f); // По центру
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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, -4.0f, 0.0f); // Зрушення управо
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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, -4.0f, 0.0f); // Зрушення вліво
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
//
// Верхній ряд
//
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f) *
Matrix.Translation(0.0f, 4.0f, 0.0f); // По центру
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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, 4.0f, 0.0f); // Зрушення управо
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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, 4.0f, 0.0f); // Зрушення вліво
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
if (flagRotate)
angle += 0.02F;
}
// Установка камери в сцену
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.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0F
angle / (float)Math.PI);
if (flagRotate)
angle += 0.02F;
}
// Сформувати сцену з урахуванням параметрів
// "положення-нормаль-колір"
device.BeginScene();
// Встановити формат обробки вершин при відображенні
device.VertexFormat = CustomVertex.PositionColored.Format;
// Намалювати трикутник даним з буфера
device.SetStreamSource(0, vb, 0);
device.Indices = ib;
DrawCubes();
device.EndScene();
// Установка камери в сцену
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;
}
private void DrawCubes()
{
//
// Середній ряд
//
//.................................................
//
// Додаткові куби
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0f,angle / (float)Math.PI / 4.0f) *
Matrix.Translation(0.0f,(float)Math.Cos(angle),(float)Math.Sin(angle));
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
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,
(float)Math.Sin(angle),
(float)Math.Cos(angle));
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
device.Transform.World = Matrix.RotationYawPitchRoll(
angle / (float)Math.PI,
angle / (float)Math.PI * 2.0f,
angle / (float)Math.PI / 2.0f) *
Matrix.Translation(
-4.0f,
(float)Math.Cos(angle),
(float)Math.Sin(angle));
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList, 0, 0, 8, 0, indices.Length / 3);
if (flagRotate)
angle += 0.02F;
}
Тут ми хочемо отримати обертання додаткових кубів навколо трьох центральних кубів, розташованих по горизонталі. Щоб цього досягти, слід додати буфер глибини в пристрій device.
Існують різні формати буферів глибини, але більшість сучасних графічних плат підтримують 16-розрядні буфери глибини. Тому використовуємо саме таку глибину.
public void InitializeGraphics()
{
// Створення об'єкту і настройка параметрів представлення
// Створити об'єкт параметрів представлення
PresentParameters presentParams = new PresentParameters();
// Встановити віконний режим
presentParams.Windowed = true;
// Скидати вміст буфера, якщо він не готовий до представлення
presentParams.SwapEffect = SwapEffect.Discard;
// Настройка буфера глибини для параметрів пристрою
presentParams.EnableAutoDepthStencil = true;
presentParams.AutoDepthStencilFormat =
Microsoft.DirectX.Direct3D.DepthFormat.D16;
// Створити об'єкт пристрою і зберегти посилання на нього
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, presentParams);
// Створити вершинний буфер
// .................................................
}
Зникнення сцени після додавання параметрів буфера глибини відбулося тому, що цей буфер не був очищений
protected override void OnPaint(PaintEventArgs e)
{
// Очистити кольором клієнтську область форми
device.Clear(ClearFlags.Target
| ClearFlags.ZBuffer,
System.Drawing.Color.CornflowerBlue,
1.0F, 0);
..........................................
}
Last modified: Tuesday, 1 November 2011, 10:14 AM
You are logged in as student7 student7 (Logout)