Навигация
Категории
C++,C#,C [19]
Уроки по средам разработки приложений с использованием C,C++,C#, а также .Net, DirectX, OpenGL и других
Delphi [14]
Уроки работы в среде программирования Delphi
Basic [13]
Уроки разработки приложений в среде Basic
DirectX [8]
Уроки по работе с DirectX, включая Direct3D и другие инструменты
Web [7]
Уроки по "Веб-программированию"
JavaScript [12]
Уроки по кодингу в Java и JavaScript
XNA [9]
Статьи и уроки программирование в среде XNA C++&C#
Профиль
Статистика
Rambler's Top100

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Locations of visitors to this page
Главная » Статьи » Программирование » XNA

Урок 6. Как создавать и использовать индексы для рисования сложных 3D объектов
Создание и использование индексов для рисования сложных 3D-объектов. За основу взят проект из урока "Как создавать и использовать матрицы трансформации".

Шаг 1. Начнём с изменения тех методов которые уже использовались в нашем проекте - облегчим методыLoadContent() и Draw() путём переноса из них части кода в отдельные методы. Начнём с метода LoadContent(): уберём из него весь код создания вершин и загрузки шейдера, а на его место вставим код вызова методов СreateVertexList(),СreateIndexList() и СreateEffect() в которых и будут создаваться вершины, индексы и шейдер. Данные методы мы реализуем чуть позже.
1
2
3
4
5
6
7
8
9
10
11
12
13
protected override void LoadContent()
{
СreateVertexList(); // создать вершины
СreateIndexList(); // создать индексы

// создать объект Effect используя контент менеджер
effect = Content.Load<Effect>("Effect");

 
// создать описание формата вершин
vertexDeclaration = new VertexDeclaration(
graphics.GraphicsDevice,
VertexPositionColor.VertexElements);
}

 

Шаг 2. Из метода Draw() уберём весь код рисования 3D-объекта и вставим на его место вызов метода DrawCube()который после реализации будет рисовать куб.
1
2
3
4
5
6
7
8
9
10
11
protected override void Draw(GameTime gameTime)
{
// отчистка экрана в синий цвет
graphics.GraphicsDevice.Clear(Color.Blue);
 
// нарисовать куб
DrawCube();
 
// вывод сцены на экран
base.Draw(gameTime);
}

 

Шаг 3. Добавим в класс Program новое поле indexList которое будет массивом индексов.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Program : Game
{
// графический компонент
GraphicsDeviceManager graphics;
 
// массив вершин
VertexPositionColor[] vertexList;
 
// массив индексов
int[] indexList;
 
// описание формата вершин
VertexDeclaration vertexDeclaration;
 
// эффект (шейдер)
Effect effect;
 
// счетчик времени
float time;

 

Шаг 4. Начнём создавать и реализовывать новые методы в классе Programm. Первым будет метод СreateVertexList() в котором мы должны написать код создания массива вершин. Этот код очень похож на тот что был у наc раньше в методе LoadContent(), но отличается от него тем, что вместо 3-х вершин описывающих углы треугольника мы создаём 8 вершин описывающик углы куба.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
/// создание и заполнение массива вершин
/// </summary>
private void СreateVertexList()
{
// создать массив-контейнер для хранения трёх вершин
vertexList = new VertexPositionColor[8];
 
// верхний набот вершин
vertexList[0] = new VertexPositionColor(new Vector3(-1.0f, -1.0f, 1.0f), Color.Yellow);
vertexList[1] = new VertexPositionColor(new Vector3(1.0f, -1.0f, 1.0f), Color.Red);
vertexList[2] = new VertexPositionColor(new Vector3(-1.0f, -1.0f, -1.0f), Color.Red);
vertexList[3] = new VertexPositionColor(new Vector3(1.0f, -1.0f, -1.0f), Color.Yellow);
 
// нижний набор вершин
vertexList[4] = new VertexPositionColor(new Vector3(-1.0f, 1.0f, 1.0f), Color.Red);
vertexList[5] = new VertexPositionColor(new Vector3(1.0f, 1.0f, 1.0f), Color.Yellow);
vertexList[6] = new VertexPositionColor(new Vector3(-1.0f, 1.0f, -1.0f), Color.Yellow);
vertexList[7] = new VertexPositionColor(new Vector3(1.0f, 1.0f, -1.0f), Color.Red);
}

 

Шаг 5. Создадим метод СreateIndexList(). Данный метод должен позаботиться о создании массива индексов. Каждые 3 индекса в массиве индексов ссылаются на 3 вершины в массиве вершин тем самым описывают 3 угла треугольника. Пара треугольников, или 6 индексов составляют грань куба.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/// <summary>
/// создание и заполнение массива индексов
/// </summary>
private void СreateIndexList()
{
// создаём массив для 36 индексов
indexList = new int[36];
 
// пара треугольников нижней грани куба
indexList[0] = 3; indexList[1] = 1; indexList[2] = 0;
indexList[3] = 2; indexList[4] = 3; indexList[5] = 0;
 
// пара треугольников верхней грани куба
indexList[6] = 4; indexList[7] = 5; indexList[8] = 7;
indexList[9] = 7; indexList[10] = 6; indexList[11] = 4;
 
// пара треугольников левой грани куба
indexList[12] = 4; indexList[13] = 2; indexList[14] = 0;
indexList[15] = 2; indexList[16] = 4; indexList[17] = 6;
 
// пара треугольников передней грани куба
indexList[18] = 6; indexList[19] = 3; indexList[20] = 2;
indexList[21] = 3; indexList[22] = 6; indexList[23] = 7;
 
// пара треугольников правой грани куба
indexList[24] = 1; indexList[25] = 3; indexList[26] = 7;
indexList[27] = 7; indexList[28] = 5; indexList[29] = 1;
 
// пара треугольников задней грани куба
indexList[30] = 0; indexList[31] = 1; indexList[32] = 5;
indexList[33] = 5; indexList[34] = 4; indexList[35] = 0;
}

 

Шаг 6. Создадим метод DrawCube() и вставим в него код который мы вырезали из метода Draw().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <summary>
/// рендеринг куба
/// </summary>
void DrawCube()
{
// использовать для отрисовки эффект BasicEffect
effect.Begin();
 
// начать отрисовку первого прохода
effect.CurrentTechnique.Passes[0].Begin();
 
// указать описание формата вершин
graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
 
// отключить отсечение невидимых поверхностей
graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
 
// нарисовать треугольник используя массив вершин
graphics.GraphicsDevice.DrawUserPrimitives
(PrimitiveType.TriangleList, vertexList, 0, 1);
 
// завершить первый проход
effect.CurrentTechnique.Passes[0].End();
 
// завершить использование эффекта BasicEffect
effect.End();
}

 

Шаг 7. Заменим вызов метода graphics.GraphicsDevice.DrawUserPrimitives() на вызов методаgraphics.GraphicsDevice.DrawUserIndexedPrimitives(). Второй метод отличается от первого тем, что он рисует индексированные примитивы, т.е. кроме массива вершин использует массив индексов.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>
/// рендеринг куба
/// </summary>
void DrawCube()
{
// использовать для отрисовки эффект BasicEffect
effect.Begin();
 
// начать отрисовку первого прохода
effect.CurrentTechnique.Passes[0].Begin();
 
// указать описание формата вершин
graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
 
// отключить отсечение невидимых поверхностей
graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
 

// нарисовать куб используя массив вершин и индексов
graphics.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.TriangleList, // тип примитивов
vertexList, // массив вершин
0, // позиция первой используемой вершины
8, // кол-во используемых вершин
indexList, // массив индексов
0, // позиция первого используемого индекса
12); // кол-во выводимых примитивов
 
// завершить первый проход
effect.CurrentTechnique.Passes[0].End();
 
// завершить использование эффекта BasicEffect
effect.End();
}

 

Итак мы нарисовали куб состоящий из 12 треугольников, но вместо 36 вершин (по 3 на треугольник) мы создали только 8 (описывающих углы куба) и с помощью индексов мы из 8 вершин собрали 12 треугольников. Теперь при запуске приложения вы увидите окно в котором будет "летать" цветной куб.

В секции загрузок лежит архив с исходным кодом этого и других уроков.



Источник: http://www.xnadev.ru/articles.php?article_id=13
Категория: XNA | Добавил: gforcer (31.01.2010) | Автор: Админ
Просмотров: 880 | Комментарии: 1 | Теги: программирование, xna, C#, c++ | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Друзья сайта
Демотиваторы
Copyright Зямаев Денис © 2017