Как нарисовать цилиндр в OpenTK (.Glu.Cylinder)? - PullRequest
1 голос
/ 13 ноября 2010

Как нарисовать цилиндр с OpenGL в OpenTK?

Ответы [ 2 ]

1 голос
/ 14 ноября 2010

Пример кода из моего старого проекта.Это создаст «открытый цилиндр» (верх и низ пусты).

int segments = 10; // Higher numbers improve quality 
int radius = 3;    // The radius (width) of the cylinder
int height = 10;   // The height of the cylinder

var vertices = new List<Vector3>();
for (double y = 0; y < 2; y++)
{
    for (double x = 0; x < segments; x++)  
    {
        double theta = (x / (segments - 1)) * 2 * Math.PI;

        vertices.Add(new Vector3()
        {
            X = (float)(radius * Math.Cos(theta)),
            Y = (float)(height * y),
            Z = (float)(radius * Math.Sin(theta)),
        });
    }
}

var indices = new List<int>();
for (int x = 0; x < segments - 1; x++)
{
    indices.Add(x);
    indices.Add(x + segments);
    indices.Add(X + segments + 1);

    indices.Add(x + segments + 1);
    indices.Add(x + 1);
    indices.Add(x);
}

Теперь вы можете визуализировать цилиндр следующим образом:

GL.Begin(BeginMode.Triangles);
foreach (int index in indices)
    GL.Vertex3(vertices[index]);
GL.End();

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

1 голос
/ 13 ноября 2010

Генерация геометрии для цилиндра довольно проста (давайте рассмотрим цилиндр с Z-выравниванием). Позвольте мне использовать псевдокод:

points = list of (x,y,z)
    where x = sin(a)*RADIUS, y = cos(a)*RADIUS, z = b,
    for each a in [0..2*PI) with step StepA,
    for each b in [0..HEIGHT] with step StepB

Об индексах: допустим, N равно количеству "уровней" или "срезов" цилиндра (зависит от высоты и шага B), а M равно количеству точек на каждом "срезе" "(что зависит от шага А).

Цилиндр содержит несколько квадов, каждый из которых охватывает 2 соседних среза, поэтому индексы будут выглядеть так:

indices = list of (a,b,c,d)
    where a = M * slice + point,
          b = M * slice + (point+1) % M,
          c = (M+1) * slice + (point+1) % M,
          d = (M+1) * slice + point
    for each slice in [0..N-2]
    for each point in [0..M-1]

Если вам нужны нормали для цилиндра, их просто сгенерировать:

normals = (x/RADIUS,y/RADIUS,0)
    for each (x,y,z) in points

Вот и все, что касается круглой части цилиндра, вам также могут понадобиться «колпачки», но я считаю, что их легко сделать.

Я оставлю забавную часть перевода моего псевдокода на выбранный вами язык. :)

Остальное - создавать / связывать VBO, загружать геометрию, устанавливать указатели, использовать выбранный вами шейдер и вызывать glDrawArrays (...) - это должно освещаться в любом руководстве OpenGL 3; ты знаком с этой частью?

...