OpenTK: использование разных цветов с VBO - PullRequest
2 голосов
/ 28 октября 2011

Ситуация: Я рисую с OpenGL в C # с библиотекой OpenTK.

.

Проблема: Я не могу выбрать, какой из моих буферов / наборов вершин нарисовать.

.

Setup-Function:

var vertices = new Vertex[..];

Создание вершин

foreach( .. ) 
{
 Byte4 color = new Byte4();
 color.R     = 255;
 color.G     = 0;
 color.B     = 0;
 color.A     = 100;

 Vertex vertex;
 vertex.Position = new Vector3(.....);
 vertex.Color    = color;

 vertices[index] = vertex;
}

Генерация / связывание буферов.

vbo_size = vertices.Length;
GL.GenBuffers(1, out vbo_id);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
GL.BufferData<Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(vbo_size * Vertex.SizeInBytes), vertices, BufferUsageHint.StaticDraw);
GL.InterleavedArrays(InterleavedArrayFormat.C4ubV3f, 0, IntPtr.Zero);

* Vertex.SizeInBytes равно 16, если это имеет значение.

.

Рендер-код:

GL.Enable(EnableCap.DepthTest);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
..
GL.Enable(EnableCap.ColorArray);
GL.DrawArrays(BeginMode.Points, 0, vbo_size);
GL.Disable(EnableCap.ColorArray);
..
glControl1.SwapBuffers();

.

Что хотел бы сделать:

В установочном коде я создаю свои вершины (вершина включает положение и цвет). Я создаю один набор прямо сейчас, но я хотел бы создать еще один (точно такой же код с разными значениями цвета). Я сделал это, и, конечно, можно создать его и связать со вторичным буфером (vbo_id / vbo_secondary_id). Но как мне это нарисовать?

Что-то вроде этого - то, что я ищу:

RenderNormalColors()
{
  GL.UseVboId(vbo_id);
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
}

RenderAlternativeColors()
{
  GL.UseVboId(vbo_id_secondary);
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
}

GL.DrawArrays, кажется, берет все без контроля над тем, что рисовать.

Все в вершинах / массивах будет / будет идентичным, кроме цветов. Мне просто нужно визуализировать те же объекты - тысячи точек - с помощью другой «схемы цветов».

Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 02 ноября 2011

Так что я исправил это.То, как я изначально думал, что решение будет.

Я создал один массив для вершин (позиций) и два отдельных массива с цветами (C # "Color").

  vertices  = new Vector3[evaluations.Count];
  colors    = new int[evaluations.Count];
  altcolors = new int[evaluations.Count];

ТогдаЯ связал их с разными буферами.

  vbo_size = vertices.Length; // Necessary for rendering later on
  GL.GenBuffers(1, out vbo_id);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(vertices.Length * BlittableValueType.StrideOf(vertices)), // strideof means what?
                vertices, BufferUsageHint.StaticDraw);

  GL.GenBuffers(1, out vbo_color_id);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(colors.Length * BlittableValueType.StrideOf(vertices)),
                colors, BufferUsageHint.StaticDraw);

  GL.GenBuffers(1, out vbo_color_id_alt);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id_alt);
  GL.BufferData(BufferTarget.ArrayBuffer,
                new IntPtr(altcolors.Length * BlittableValueType.StrideOf(vertices)),
                altcolors, BufferUsageHint.StaticDraw);

Обратите внимание на "vbo_color_id" и "vbo_color_id_alt".Они используются в Render ()

selected_vbo = либо color_id_alt или color_id

  GL.BindBuffer(BufferTarget.ArrayBuffer, selected_vbo);
  GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
  GL.EnableClientState(ArrayCap.ColorArray);

  GL.EnableClientState(ArrayCap.VertexArray);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);
0 голосов
/ 02 ноября 2011

Я использовал это, чтобы иметь возможность выбирать точки в облаке точек. Каждая точка получает в альтернативной схеме цветов уникальный цвет (хранится в словаре, который указывает на идентификатор точки (индекс)).

Когда я щелкаю мышью, он получает текущий пиксель и проверяет список. Если он найдет цвет, присутствующий в наборе, он будет знать, по какой точке щелкнули.

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

Я отображаю альтернативные цвета, выбираю цвет пикселя под мышью, но не использую «swapbuffer ()», поэтому он никогда не будет отображаться на экране. Затем я отрисовываю его снова с использованием основных цветов.

Довольно изящно.

public void RenderAlternativeColorsAndPick(int x, int y)
{
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color_id_alt);
  GL.ColorPointer(4, ColorPointerType.UnsignedByte, sizeof(int), IntPtr.Zero);
  GL.EnableClientState(ArrayCap.ColorArray);

  GL.EnableClientState(ArrayCap.VertexArray);
  GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_id);
  GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, new IntPtr(0));
  GL.DrawArrays(BeginMode.Points, 0, vbo_size);

  // Psuedo code sorry
  GL.GetPixelColor(x,y)
  SelectedPoint    = dictionary<color,int>.findValuebyKey(thePixelsColor)
}

Надеюсь, это поможет кому-то в будущем.

...