Навигация
· XNA FAQ
· С чего начать
· Конкурсы
· Обратная связь
· XNA Блоги
Сейчас на сайте
· Гостей: 1

· Пользователей: 0

· Всего пользователей: 3,684
· Новый пользователь: headron
Последние фото
Эх, чуть не проспал закрытие.
Эх, чуть не проспал ...
Альбом: XNA Engine

GB
GB
Альбом: XNA Engine

South Park Coon & Friends
South Park Coon & Fr...
Альбом: XNA Games

Блоги
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
dampirik
» Реклама,статистик...
Chort
» XNA и StartCoroutine
Chort
» Curve Class
dampirik
» Реклама, статисти...
dampirik
» Увеличение скорос...
dampirik
» Реклама, статисти...
general
» Распаковка DxtCom...
general
» Как работать с XN...
Поддержка
microsoft.com
1gb.ru - Дом для вашего сайта
Статистика посещений:

Урок 8. Как рисовать точки, линии и другие 3D примитивы

Урок 8. Как рисовать точки, линии и другие 3D примитивы.


В этом уроке мы рассмотрим, как можно нарисовать  простейшие примитивы (точки, линии, треугольники).  Это дословный перевод статьи из MSDN - How To: Draw Points, Lines, and Other 3D Primitives.

В XNA Framework, 3D примитив это специальный тип 3D объекта, который определяет, как графическое устройство интерпретирует вершины в вершинном буфере.  Мы приведем пример, как использовать точки, линии и треугольники, являющиеся основой рисования на самом низком уровне.

Пометка – для простейшей отрисовки примитивов, кроме координат, вам необходимо создать экземпляр объекта BasicEffect а так же несколько матриц трансформации. Ссылки по теме - How To: Use BasicEffect, и на нашем сайте - Как рисовать простые 3D-объекты с помощью BasicEffect.

Исходный код примера можно загрузить с сайта Microsoft или с нашего сайта (отличается только русскими комментариями)

Рисуем точки

1. Нужно создать список 3D вершин, которые определяют рисуемые точки.

Следующий код создает 8 точек и сохраняет их в массиве VertexPositionColor[] pointList;

1
2
3
4
5
6
7
8
9
10
pointList = new VertexPositionColor[points];
 
for (int x = 0; x < points / 2; x++)
{
    for (int y = 0; y < 2; y++)
    {
        pointList[(x * 2) + y] = new VertexPositionColor(
            new Vector3(x * 100, y * 100, 0), Color.White);
    }
}

 


Визуально точки будут выглядеть так -




На рисунке показаны 8 точек определяющих 6 треугольников нарисованных на плоскости Z (z=0). Координаты первой точки = (0,0,0). Камера размещена в точке (0,0,1) и смотрит на начало координат (0,0,0). Ортогональная проекция задана двумя точками – верхняя-левая (0,0) и нижняя-правая (800,600). Кроме этого мы используем дополнительную матрицу трансформации, которая смещает наши точки к центру экрана. Следующий код показывает создание 2-ух из 3-ех необходимых нам матриц. 3-яя матрица (мировая) для смещения точек к центру экрана создается в методе InitializeEffect()

1
2
3
4
5
6
7
8
9
10
11
12
viewMatrix = Matrix.CreateLookAt(
    new Vector3(0.0f, 0.0f, 1.0f),
    Vector3.Zero,
    Vector3.Up
    );
 
projectionMatrix = Matrix.CreateOrthographicOffCenter(
    0,
    (float)GraphicsDevice.Viewport.Width,
    (float)GraphicsDevice.Viewport.Height,
    0,
    1.0f, 1000.0f);

 



2. Используя свойство GraphicsDevice.RenderState.PointSize установим размер выводимых точек.

В нашем примере размер равен 10. На экране вы увидите квадратные точки.

GraphicsDevice.RenderState.PointSize = 10;

3. Выводим точки на экран используя функцию GraphicsDevice.DrawUserPrimitives(..) которая в качестве первого аргумента принимает тип выводимого примитива - PrimitiveType.PointList. Тип примитива определяет как данные в переданном массиве вершин будут интерпретированы и показаны.

1
2
3
4
5
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(
           PrimitiveType.PointList, // тип примитива для отрисовки
           pointList, // массив точек
           0,  // индекс первой используемой вершины в массиве
           8); // количество примитивов (точек)

 



Рисуем линии

1. В дополнение к списку 3D вершин точек нужно создать массив индексов для нумерации/индексации данных о вершинах.

Нижеприведенный код определяет индексы для серии линий

1
2
3
4
5
6
7
8
9
10
       // массив индексов для линий
       lineListIndices = new short[(points * 2) - 2];
 
       // заполняем индексы
       for (int i = 0; i < points - 1; i++)
       {
            lineListIndices[i * 2] = (short)(i);
            lineListIndices[(i * 2) + 1] = (short)(i + 1);
       }
 

 


Другими словами, данный код равнозначен следующему и определяет линии соеденяющие наши точки - pointList[0] и pointList[1], pointList[1] и pointList[2], и так далее 7 линий между 8-ми точек.

lineListIndices = new short[14]{ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7 };

2. Выводим линии на экран используя функцию GraphicsDevice.DrawUserIndexedPrimitives (..) которая в качестве первого аргумента принимает тип выводимого примитива - PrimitiveType. LineList


1
2
3
4
5
6
7
8
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
        PrimitiveType.LineList, // тип примитива для отрисовки
        pointList, // массив точек
        0,  // смещение, добавляемое для каждого индекса в индексном буфере
        8,  // количество вершин
        lineListIndices,  // индексный буфер соеденяющий наши точки по парам
        0,  // первый используемый индекс
        7); // количество примитивов (линий)

 




Рисуем ленту линий (Line Strip)

1. Для определения ленты из линий нам понадобится новый массив индексов в котором последовательно будут соеденены точки из массива вершин.

Для ленты нам понадобится в двое меньше индексов так как лента подразумевает последовательно соединенные примитивы (точки).

1
2
3
4
5
6
7
8
9
      // массив индексов для линий
      lineStripIndices = new short[points];
 
      // заполняем индексы последовательно соеденяя одну точку за другой
      for (int i = 0; i < points; i++)
      {
           lineStripIndices[i] = (short)(i);
      }
 

 


Или так –

lineStripIndices = new short[8]{ 0, 1, 2, 3, 4, 5, 6, 7 };

2. Выводим ленту линий на экран используя функцию GraphicsDevice.DrawUserIndexedPrimitives (..) которая в качестве первого аргумента принимает тип выводимого примитива - PrimitiveType. LineStrip. Пометка – рисование лент обычно более эффективно чем рисование списков - с точки зрения производительности, так как индексы выводимых вершин содержат меньшее количество повторений.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 for (int i = 0; i < pointList.Length; i++)
     pointList[i].Color = Color.Red;
 
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
        PrimitiveType.LineStrip, // тип примитива для отрисовки
        pointList, // массив точек
        0, // смещение, добавляемое для каждого индекса в индексном буфере
        8,  // количество вершин для отрисовки
        lineStripIndices, // массив индесов (последовательность точек)
        0,  // первый используемый индекс
        7); // количество примитивов (линий)
 
for (int i = 0; i < pointList.Length; i++)
    pointList[i].Color = Color.White;

 


В этом примере мы сначала устанавливаем цвет точек в красный и затем рисуем, после чего меняем цвет точек обратно.  Ленты рисуются красным цветом, а списки цветом по умолчанию – белым.

Рисуем треугольники

1. Создаем новый массив индексов, в котором будет пронумерованный список треугольников, по 3 вершины на один треугольник. Массив вершин не меняем.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
triangleListIndices = new short[(width - 1) * (height - 1) * 6];
 
for (int x = 0; x < width - 1; x++)
{
    for (int y = 0; y < height - 1; y++)
    {
        triangleListIndices[(x + y * (width - 1)) * 6] = (short)(2 * x);
        triangleListIndices[(x + y * (width - 1)) * 6 + 1] = (short)(2 * x + 1);
        triangleListIndices[(x + y * (width - 1)) * 6 + 2] = (short)(2 * x + 2);
 
        triangleListIndices[(x + y * (width - 1)) * 6 + 3] = (short)(2 * x + 2);
        triangleListIndices[(x + y * (width - 1)) * 6 + 4] = (short)(2 * x + 1);
        triangleListIndices[(x + y * (width - 1)) * 6 + 5] = (short)(2 * x + 3);
    }
}

 



Этот код индексирует вершины так что каждые 3 точки у нас образуют один треугольник, причем в каждом треугольнике есть общие вершины с соседним. Ниже аналог этого кода –

triangleListIndices = new short[18]{ 0, 1, 2, 2, 1, 3, 2, 3, 4, 4, 3, 5, 4, 5, 6, 6, 5, 7 };

2. Выводим список треугольников на экран используя функцию GraphicsDevice.DrawUserIndexedPrimitives (..) которая в качестве первого аргумента принимает тип выводимого примитива - PrimitiveType.TriangleList

1
2
3
4
5
6
7
8
9
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
        PrimitiveType.TriangleList, // тип примитива для отрисовки
        pointList, // массив точек
        0,   // смещение, добавляемое для каждого индекса в индексном буфере
        8,   // количество вершин для отрисовки
        triangleListIndices,  // массив индесов
        0,   // первый используемый индекс
        6);  // количество примитивов (треугольников)
 

 



Рисуем ленту из треугольников (TriangleStrip)

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

1
2
3
4
5
6
7
8
   // массив индексов для треугольников
   triangleStripIndices = new short[points];
 
   // заполняем индексы
   for (int i = 0; i < points; i++)
   {
       triangleStripIndices[i] = (short)i;
   }

 



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

Аналог кода создания индексов –

triangleStripIndices = new short[8]{ 0, 1, 2, 3, 4, 5, 6, 7 };

2. Выводим ленту треугольников на экран используя функцию GraphicsDevice.DrawUserIndexedPrimitives (..) которая в качестве первого аргумента принимает тип выводимого примитива - PrimitiveType.TriangleStrip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for (int i = 0; i < pointList.Length; i++)
     pointList[i].Color = Color.Red;
 
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
        PrimitiveType.TriangleStrip, // тип примитива для отрисовки
        pointList, // массив точек
        0, // смещение, добавляемое для каждого индекса в индексном буфере
        8,  // количество вершин для отрисовки
        triangleStripIndices, // массив индесов
        0,  // первый используемый индекс
        6);  // количество примитивов (треугольников)
 
for (int i = 0; i < pointList.Length; i++)
     pointList[i].Color = Color.White;
 

 



В этом коде мы так же с начала меняем цвет вершин перед отрисовкой.

В заключение приведем схему индексации различных примитивов (еще называют топологией примитивов)



Комментарии
#1 | Chort 02.05.2009 01:22:16
Всегда TriangleFan где-то потеряют Grin
#2 | mike 02.05.2009 01:31:18
ты прав, про TriangleFan нет ни слова.
#3 | wlad 14.09.2009 23:52:41
Статья толковая. Обязательно переварю...
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Отлично! Отлично! 100% [3 Голоса]
Очень хорошо Очень хорошо 0% [Нет голосов]
Хорошо Хорошо 0% [Нет голосов]
Удовлетворительно Удовлетворительно 0% [Нет голосов]
Плохо Плохо 0% [Нет голосов]
Авторизация
Логин

Пароль



Вы не зарегистрированы?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Мини-чат
Вы должны авторизироваться, чтобы добавить сообщение.

27.08.2014
Я умею немного на asp.net + html и css

22.08.2014
на ASP mvc 3 есть пару проектов. Могу помочь, если нужно. Обидно, если закроется Frown

21.08.2014
я тоже ноль

21.08.2014
Я в вебе только с php занимался да и то на уровне чтоб работало.

21.08.2014
Я в вебе полный ноль…

21.08.2014
Переводить его надо, хоть на ту же азуру. И двиг менять на что-то современное. Если есть веб-разрабы - можем скооперироваться. Один делать не буду.

21.08.2014
не знаю всех нюансов по оплате и все хорошее когда нибудь заканчивается

21.08.2014
А что случилось?

21.08.2014
похоже сайт будет работать до 28го числа

09.08.2014
Апи пока не видел. Но есть приложение в магазине Live Lock Screen BETA, так что думаю скоро будет

08.08.2014
Я про API для Update1. На нем работает это

08.08.2014
А что именно нужно? Чтото и сейчас открыто http://msdn.micro.
...105).aspx

06.08.2014
Кто-нибудь слышал об открытии доступа к Lock Screen Api?

31.07.2014
VPDExpress на базе MVS 2012, ни в какую не ловит исключения. Даже если их сам создаешь. И всех так?

25.07.2014
С днем системного администратора причастных к этой профессии! По случаю - тортик от жены

RSS каналы сайта
XNA - Новости
XNA - Статьи
XNA - Форум
XNA - Галерея
XNA - Файлы
Время загрузки: 0,08 секунд 8,709,446 уникальных посетителей