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

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

· Всего пользователей: 7,142
· Новый пользователь: Sarahseato
Последние фото
Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Thurs Puzzle
Thurs Puzzle
Альбом: XNA Games

Блоги
general
» Unity3D – Chunky ...
general
» Unity3D: Simple p...
dampirik
» Записки программи...
dampirik
» Локализация прило...
dampirik
» Эффективность рас...
general
» HLSL: Шейдер воды
general
» Unity 3D: Управле...
general
» Unity 3D: FPS scr...
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
Поддержка
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% [Нет голосов]
Авторизация
Логин

Пароль



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

11.12.2023

11.12.2023
[img]https://x.pin
-up-world.com/imag
es/img4.jpg[/img]
[url=https://ofoi.
cenditt.loan/new-k
atiana-kay-fucking
-with-lucky-fan-p1
-porn-scenes/]133K
67% New Katiana

11.12.2023
[img]https://wwt.s
sgameadmin2.com/im
ages/img4.jpg[/img
]
[url=https://k.smi
letaxservice.com/r
edirect/SFpEdDR1cG
V4czNKMmxlQi9tVytI
d3dxWW9GWTd5Zk52TD
VVMG1mc3YvUmlDMWUw

11.12.2023

11.12.2023

10.12.2023
[img]https://ey.os
prey-holidays.uk/i
mages/img10.jpg[/i
mg]
[url=https://nby.h
ighlyresponsible.c
om/696488/sexyfeet
girl2020-gotta-kee
p-them-soft-lookin
g-

30.11.2023
[img]https://nuggi
e.army/images/img1
5.jpg[/img]
German Porno kostenlos - Deutsche Pornos &amp; Pornofilme. [url=ht

30.11.2023

30.11.2023
[img]https://where
ijoin.com/images/i
mg8.jpg[/img]
Voir Films VF VOSTFR - . [url=http://mvig.j
ulieemontelaro.com
/]omegleX

30.11.2023
[img]https://steam
unlocked.tangobliv
ion.com/images/img
14.jpg[/img]
Top - Rated Live Sex Cam Videos to Watch Online. [

29.11.2023

29.11.2023
[img]https://chaii
t.com/images/img8.
jpg[/img]
Ottmaza.live - Ottmaza.Com Official Website | Ottmaza | Ottmaza.Net | Ottmaz

29.11.2023
[img]https://ezyja
mb.co.uk/images/im
g10.jpg[/img]
Free Porn - Sex, Tube Videos, XXX Pics, Pussy in Porno

29.11.2023
[img]https://launc
hbusinessloans.org
/images/img15.jpg[
/img]
Asyalı - Koreli Japon Seks Filmleri Türkçe A

29.11.2023
[img]https://panen
poker.org/images/i
mg8.jpg[/img]
[url=http://watchm
ovies.seoullittlem
all.com/]Junkie Musik Lossless &#ff7dee MГєsica ElectrГіnica p

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