2

情况:我正在使用 C# 中的 OpenGL 和 OpenTK 库进行绘图。

.

问题:我无法选择要绘制哪一个缓冲区/顶点集。

.

设置功能:

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();

.

id喜欢做什么:

在设置代码中,我创建了我的顶点(顶点包括位置和颜色)。我现在创建了一组,但我想再创建一组(只是具有不同颜色值的相同代码)。我这样做了,当然可以创建它并将其绑定到辅助缓冲区(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 似乎在不控制绘制内容的情况下获取所有内容。

除了颜色之外,顶点/数组中的所有内容都将/是相同的。我只需要用另一个“配色方案”渲染相同的对象——数千个点。

任何帮助都将不胜感激。

4

2 回答 2

2

所以我修好了。有点像我最初认为的解决方案。

我为顶点(位置)创建了一个数组,并为颜色创建了两个单独的数组(C#“颜色”)。

  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_altcolor_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);
于 2011-11-02T10:19:46.037 回答
0

我用它来选择点云中的点。在替代颜色方案中,每个点都会获得唯一的颜色(存储在指向点 id(索引)的字典中)。

当我单击鼠标时,它会检索当前像素并检查列表。如果它找到集合中存在的颜色,它将知道单击了哪个点。

这非常好,因为我不必使用光线投射或八叉树或类似的检查。但值得注意的是,这将使您无法在屏幕上当前显示的点后面找到任何东西。

我渲染替代颜色,选择鼠标下的像素颜色,但我不使用“swapbuffer()”,因此它永远不会显示在屏幕上。然后我用 corerct 颜色再次渲染它。

很漂亮。

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)
}

希望这对将来的某人有所帮助。

于 2011-11-02T10:34:56.880 回答